LCOV - code coverage report
Current view: top level - src/backend/utils/adt - pg_upgrade_support.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 79 119 66.4 %
Date: 2023-12-05 08:11:01 Functions: 14 17 82.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  pg_upgrade_support.c
       3             :  *
       4             :  *  server-side functions to set backend global variables
       5             :  *  to control oid and relfilenumber assignment, and do other special
       6             :  *  hacks needed for pg_upgrade.
       7             :  *
       8             :  *  Copyright (c) 2010-2023, PostgreSQL Global Development Group
       9             :  *  src/backend/utils/adt/pg_upgrade_support.c
      10             :  */
      11             : 
      12             : #include "postgres.h"
      13             : 
      14             : #include "catalog/binary_upgrade.h"
      15             : #include "catalog/heap.h"
      16             : #include "catalog/namespace.h"
      17             : #include "catalog/pg_type.h"
      18             : #include "commands/extension.h"
      19             : #include "miscadmin.h"
      20             : #include "replication/logical.h"
      21             : #include "utils/array.h"
      22             : #include "utils/builtins.h"
      23             : 
      24             : 
      25             : #define CHECK_IS_BINARY_UPGRADE                                 \
      26             : do {                                                            \
      27             :     if (!IsBinaryUpgrade)                                       \
      28             :         ereport(ERROR,                                          \
      29             :                 (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),    \
      30             :                  errmsg("function can only be called when server is in binary upgrade mode"))); \
      31             : } while (0)
      32             : 
      33             : Datum
      34           0 : binary_upgrade_set_next_pg_tablespace_oid(PG_FUNCTION_ARGS)
      35             : {
      36           0 :     Oid         tbspoid = PG_GETARG_OID(0);
      37             : 
      38           0 :     CHECK_IS_BINARY_UPGRADE;
      39           0 :     binary_upgrade_next_pg_tablespace_oid = tbspoid;
      40             : 
      41           0 :     PG_RETURN_VOID();
      42             : }
      43             : 
      44             : Datum
      45        1476 : binary_upgrade_set_next_pg_type_oid(PG_FUNCTION_ARGS)
      46             : {
      47        1476 :     Oid         typoid = PG_GETARG_OID(0);
      48             : 
      49        1476 :     CHECK_IS_BINARY_UPGRADE;
      50        1476 :     binary_upgrade_next_pg_type_oid = typoid;
      51             : 
      52        1476 :     PG_RETURN_VOID();
      53             : }
      54             : 
      55             : Datum
      56        1474 : binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
      57             : {
      58        1474 :     Oid         typoid = PG_GETARG_OID(0);
      59             : 
      60        1474 :     CHECK_IS_BINARY_UPGRADE;
      61        1474 :     binary_upgrade_next_array_pg_type_oid = typoid;
      62             : 
      63        1474 :     PG_RETURN_VOID();
      64             : }
      65             : 
      66             : Datum
      67           8 : binary_upgrade_set_next_multirange_pg_type_oid(PG_FUNCTION_ARGS)
      68             : {
      69           8 :     Oid         typoid = PG_GETARG_OID(0);
      70             : 
      71           8 :     CHECK_IS_BINARY_UPGRADE;
      72           8 :     binary_upgrade_next_mrng_pg_type_oid = typoid;
      73             : 
      74           8 :     PG_RETURN_VOID();
      75             : }
      76             : 
      77             : Datum
      78           8 : binary_upgrade_set_next_multirange_array_pg_type_oid(PG_FUNCTION_ARGS)
      79             : {
      80           8 :     Oid         typoid = PG_GETARG_OID(0);
      81             : 
      82           8 :     CHECK_IS_BINARY_UPGRADE;
      83           8 :     binary_upgrade_next_mrng_array_pg_type_oid = typoid;
      84             : 
      85           8 :     PG_RETURN_VOID();
      86             : }
      87             : 
      88             : Datum
      89        1488 : binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS)
      90             : {
      91        1488 :     Oid         reloid = PG_GETARG_OID(0);
      92             : 
      93        1488 :     CHECK_IS_BINARY_UPGRADE;
      94        1488 :     binary_upgrade_next_heap_pg_class_oid = reloid;
      95             : 
      96        1488 :     PG_RETURN_VOID();
      97             : }
      98             : 
      99             : Datum
     100        1226 : binary_upgrade_set_next_heap_relfilenode(PG_FUNCTION_ARGS)
     101             : {
     102        1226 :     RelFileNumber relfilenumber = PG_GETARG_OID(0);
     103             : 
     104        1226 :     CHECK_IS_BINARY_UPGRADE;
     105        1226 :     binary_upgrade_next_heap_pg_class_relfilenumber = relfilenumber;
     106             : 
     107        1226 :     PG_RETURN_VOID();
     108             : }
     109             : 
     110             : Datum
     111         988 : binary_upgrade_set_next_index_pg_class_oid(PG_FUNCTION_ARGS)
     112             : {
     113         988 :     Oid         reloid = PG_GETARG_OID(0);
     114             : 
     115         988 :     CHECK_IS_BINARY_UPGRADE;
     116         988 :     binary_upgrade_next_index_pg_class_oid = reloid;
     117             : 
     118         988 :     PG_RETURN_VOID();
     119             : }
     120             : 
     121             : Datum
     122        1004 : binary_upgrade_set_next_index_relfilenode(PG_FUNCTION_ARGS)
     123             : {
     124        1004 :     RelFileNumber relfilenumber = PG_GETARG_OID(0);
     125             : 
     126        1004 :     CHECK_IS_BINARY_UPGRADE;
     127        1004 :     binary_upgrade_next_index_pg_class_relfilenumber = relfilenumber;
     128             : 
     129        1004 :     PG_RETURN_VOID();
     130             : }
     131             : 
     132             : Datum
     133         490 : binary_upgrade_set_next_toast_pg_class_oid(PG_FUNCTION_ARGS)
     134             : {
     135         490 :     Oid         reloid = PG_GETARG_OID(0);
     136             : 
     137         490 :     CHECK_IS_BINARY_UPGRADE;
     138         490 :     binary_upgrade_next_toast_pg_class_oid = reloid;
     139             : 
     140         490 :     PG_RETURN_VOID();
     141             : }
     142             : 
     143             : Datum
     144         490 : binary_upgrade_set_next_toast_relfilenode(PG_FUNCTION_ARGS)
     145             : {
     146         490 :     RelFileNumber relfilenumber = PG_GETARG_OID(0);
     147             : 
     148         490 :     CHECK_IS_BINARY_UPGRADE;
     149         490 :     binary_upgrade_next_toast_pg_class_relfilenumber = relfilenumber;
     150             : 
     151         490 :     PG_RETURN_VOID();
     152             : }
     153             : 
     154             : Datum
     155          88 : binary_upgrade_set_next_pg_enum_oid(PG_FUNCTION_ARGS)
     156             : {
     157          88 :     Oid         enumoid = PG_GETARG_OID(0);
     158             : 
     159          88 :     CHECK_IS_BINARY_UPGRADE;
     160          88 :     binary_upgrade_next_pg_enum_oid = enumoid;
     161             : 
     162          88 :     PG_RETURN_VOID();
     163             : }
     164             : 
     165             : Datum
     166           4 : binary_upgrade_set_next_pg_authid_oid(PG_FUNCTION_ARGS)
     167             : {
     168           4 :     Oid         authoid = PG_GETARG_OID(0);
     169             : 
     170           4 :     CHECK_IS_BINARY_UPGRADE;
     171           4 :     binary_upgrade_next_pg_authid_oid = authoid;
     172           4 :     PG_RETURN_VOID();
     173             : }
     174             : 
     175             : Datum
     176           0 : binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)
     177             : {
     178             :     text       *extName;
     179             :     text       *schemaName;
     180             :     bool        relocatable;
     181             :     text       *extVersion;
     182             :     Datum       extConfig;
     183             :     Datum       extCondition;
     184             :     List       *requiredExtensions;
     185             : 
     186           0 :     CHECK_IS_BINARY_UPGRADE;
     187             : 
     188             :     /* We must check these things before dereferencing the arguments */
     189           0 :     if (PG_ARGISNULL(0) ||
     190           0 :         PG_ARGISNULL(1) ||
     191           0 :         PG_ARGISNULL(2) ||
     192           0 :         PG_ARGISNULL(3))
     193           0 :         elog(ERROR, "null argument to binary_upgrade_create_empty_extension is not allowed");
     194             : 
     195           0 :     extName = PG_GETARG_TEXT_PP(0);
     196           0 :     schemaName = PG_GETARG_TEXT_PP(1);
     197           0 :     relocatable = PG_GETARG_BOOL(2);
     198           0 :     extVersion = PG_GETARG_TEXT_PP(3);
     199             : 
     200           0 :     if (PG_ARGISNULL(4))
     201           0 :         extConfig = PointerGetDatum(NULL);
     202             :     else
     203           0 :         extConfig = PG_GETARG_DATUM(4);
     204             : 
     205           0 :     if (PG_ARGISNULL(5))
     206           0 :         extCondition = PointerGetDatum(NULL);
     207             :     else
     208           0 :         extCondition = PG_GETARG_DATUM(5);
     209             : 
     210           0 :     requiredExtensions = NIL;
     211           0 :     if (!PG_ARGISNULL(6))
     212             :     {
     213           0 :         ArrayType  *textArray = PG_GETARG_ARRAYTYPE_P(6);
     214             :         Datum      *textDatums;
     215             :         int         ndatums;
     216             :         int         i;
     217             : 
     218           0 :         deconstruct_array_builtin(textArray, TEXTOID, &textDatums, NULL, &ndatums);
     219           0 :         for (i = 0; i < ndatums; i++)
     220             :         {
     221           0 :             char       *extName = TextDatumGetCString(textDatums[i]);
     222           0 :             Oid         extOid = get_extension_oid(extName, false);
     223             : 
     224           0 :             requiredExtensions = lappend_oid(requiredExtensions, extOid);
     225             :         }
     226             :     }
     227             : 
     228           0 :     InsertExtensionTuple(text_to_cstring(extName),
     229             :                          GetUserId(),
     230           0 :                          get_namespace_oid(text_to_cstring(schemaName), false),
     231             :                          relocatable,
     232           0 :                          text_to_cstring(extVersion),
     233             :                          extConfig,
     234             :                          extCondition,
     235             :                          requiredExtensions);
     236             : 
     237           0 :     PG_RETURN_VOID();
     238             : }
     239             : 
     240             : Datum
     241           0 : binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS)
     242             : {
     243           0 :     bool        record_init_privs = PG_GETARG_BOOL(0);
     244             : 
     245           0 :     CHECK_IS_BINARY_UPGRADE;
     246           0 :     binary_upgrade_record_init_privs = record_init_privs;
     247             : 
     248           0 :     PG_RETURN_VOID();
     249             : }
     250             : 
     251             : Datum
     252           4 : binary_upgrade_set_missing_value(PG_FUNCTION_ARGS)
     253             : {
     254           4 :     Oid         table_id = PG_GETARG_OID(0);
     255           4 :     text       *attname = PG_GETARG_TEXT_P(1);
     256           4 :     text       *value = PG_GETARG_TEXT_P(2);
     257           4 :     char       *cattname = text_to_cstring(attname);
     258           4 :     char       *cvalue = text_to_cstring(value);
     259             : 
     260           4 :     CHECK_IS_BINARY_UPGRADE;
     261           4 :     SetAttrMissing(table_id, cattname, cvalue);
     262             : 
     263           4 :     PG_RETURN_VOID();
     264             : }
     265             : 
     266             : /*
     267             :  * Verify the given slot has already consumed all the WAL changes.
     268             :  *
     269             :  * Returns true if there are no decodable WAL records after the
     270             :  * confirmed_flush_lsn. Otherwise false.
     271             :  *
     272             :  * This is a special purpose function to ensure that the given slot can be
     273             :  * upgraded without data loss.
     274             :  */
     275             : Datum
     276          10 : binary_upgrade_logical_slot_has_caught_up(PG_FUNCTION_ARGS)
     277             : {
     278             :     Name        slot_name;
     279             :     XLogRecPtr  end_of_wal;
     280             :     bool        found_pending_wal;
     281             : 
     282          10 :     CHECK_IS_BINARY_UPGRADE;
     283             : 
     284             :     /* We must check before dereferencing the argument */
     285          10 :     if (PG_ARGISNULL(0))
     286           0 :         elog(ERROR, "null argument to binary_upgrade_validate_wal_records is not allowed");
     287             : 
     288          10 :     CheckSlotPermissions();
     289             : 
     290          10 :     slot_name = PG_GETARG_NAME(0);
     291             : 
     292             :     /* Acquire the given slot */
     293          10 :     ReplicationSlotAcquire(NameStr(*slot_name), true);
     294             : 
     295             :     Assert(SlotIsLogical(MyReplicationSlot));
     296             : 
     297             :     /* Slots must be valid as otherwise we won't be able to scan the WAL */
     298             :     Assert(MyReplicationSlot->data.invalidated == RS_INVAL_NONE);
     299             : 
     300          10 :     end_of_wal = GetFlushRecPtr(NULL);
     301          10 :     found_pending_wal = LogicalReplicationSlotHasPendingWal(end_of_wal);
     302             : 
     303             :     /* Clean up */
     304          10 :     ReplicationSlotRelease();
     305             : 
     306          10 :     PG_RETURN_BOOL(!found_pending_wal);
     307             : }

Generated by: LCOV version 1.14