LCOV - code coverage report
Current view: top level - src/bin/pg_upgrade - version.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 95 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 4 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  *      version.c
       3              :  *
       4              :  *      Postgres-version-specific routines
       5              :  *
       6              :  *      Copyright (c) 2010-2026, PostgreSQL Global Development Group
       7              :  *      src/bin/pg_upgrade/version.c
       8              :  */
       9              : 
      10              : #include "postgres_fe.h"
      11              : 
      12              : #include "fe_utils/string_utils.h"
      13              : #include "pg_upgrade.h"
      14              : 
      15              : /*
      16              :  * version_hook functions for check_for_data_types_usage in order to determine
      17              :  * whether a data type check should be executed for the cluster in question or
      18              :  * not.
      19              :  */
      20              : bool
      21            0 : jsonb_9_4_check_applicable(ClusterInfo *cluster)
      22              : {
      23              :         /* JSONB changed its storage format during 9.4 beta */
      24            0 :         if (GET_MAJOR_VERSION(cluster->major_version) == 904 &&
      25            0 :                 cluster->controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
      26            0 :                 return true;
      27              : 
      28            0 :         return false;
      29            0 : }
      30              : 
      31              : /*
      32              :  * old_9_6_invalidate_hash_indexes()
      33              :  *      9.6 -> 10
      34              :  *      Hash index binary format has changed from 9.6->10.0
      35              :  */
      36              : void
      37            0 : old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
      38              : {
      39            0 :         int                     dbnum;
      40            0 :         FILE       *script = NULL;
      41            0 :         bool            found = false;
      42            0 :         char       *output_path = "reindex_hash.sql";
      43              : 
      44            0 :         prep_status("Checking for hash indexes");
      45              : 
      46            0 :         for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
      47              :         {
      48            0 :                 PGresult   *res;
      49            0 :                 bool            db_used = false;
      50            0 :                 int                     ntups;
      51            0 :                 int                     rowno;
      52            0 :                 int                     i_nspname,
      53              :                                         i_relname;
      54            0 :                 DbInfo     *active_db = &cluster->dbarr.dbs[dbnum];
      55            0 :                 PGconn     *conn = connectToServer(cluster, active_db->db_name);
      56              : 
      57              :                 /* find hash indexes */
      58            0 :                 res = executeQueryOrDie(conn,
      59              :                                                                 "SELECT n.nspname, c.relname "
      60              :                                                                 "FROM      pg_catalog.pg_class c, "
      61              :                                                                 "          pg_catalog.pg_index i, "
      62              :                                                                 "          pg_catalog.pg_am a, "
      63              :                                                                 "          pg_catalog.pg_namespace n "
      64              :                                                                 "WHERE     i.indexrelid = c.oid AND "
      65              :                                                                 "          c.relam = a.oid AND "
      66              :                                                                 "          c.relnamespace = n.oid AND "
      67              :                                                                 "          a.amname = 'hash'"
      68              :                         );
      69              : 
      70            0 :                 ntups = PQntuples(res);
      71            0 :                 i_nspname = PQfnumber(res, "nspname");
      72            0 :                 i_relname = PQfnumber(res, "relname");
      73            0 :                 for (rowno = 0; rowno < ntups; rowno++)
      74              :                 {
      75            0 :                         found = true;
      76            0 :                         if (!check_mode)
      77              :                         {
      78            0 :                                 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
      79            0 :                                         pg_fatal("could not open file \"%s\": %m", output_path);
      80            0 :                                 if (!db_used)
      81              :                                 {
      82            0 :                                         PQExpBufferData connectbuf;
      83              : 
      84            0 :                                         initPQExpBuffer(&connectbuf);
      85            0 :                                         appendPsqlMetaConnect(&connectbuf, active_db->db_name);
      86            0 :                                         fputs(connectbuf.data, script);
      87            0 :                                         termPQExpBuffer(&connectbuf);
      88            0 :                                         db_used = true;
      89            0 :                                 }
      90            0 :                                 fprintf(script, "REINDEX INDEX %s.%s;\n",
      91            0 :                                                 quote_identifier(PQgetvalue(res, rowno, i_nspname)),
      92            0 :                                                 quote_identifier(PQgetvalue(res, rowno, i_relname)));
      93            0 :                         }
      94            0 :                 }
      95              : 
      96            0 :                 PQclear(res);
      97              : 
      98            0 :                 if (!check_mode && db_used)
      99              :                 {
     100              :                         /* mark hash indexes as invalid */
     101            0 :                         PQclear(executeQueryOrDie(conn,
     102              :                                                                           "UPDATE pg_catalog.pg_index i "
     103              :                                                                           "SET     indisvalid = false "
     104              :                                                                           "FROM    pg_catalog.pg_class c, "
     105              :                                                                           "                pg_catalog.pg_am a, "
     106              :                                                                           "                pg_catalog.pg_namespace n "
     107              :                                                                           "WHERE   i.indexrelid = c.oid AND "
     108              :                                                                           "                c.relam = a.oid AND "
     109              :                                                                           "                c.relnamespace = n.oid AND "
     110              :                                                                           "                a.amname = 'hash'"));
     111            0 :                 }
     112              : 
     113            0 :                 PQfinish(conn);
     114            0 :         }
     115              : 
     116            0 :         if (script)
     117            0 :                 fclose(script);
     118              : 
     119            0 :         if (found)
     120              :         {
     121            0 :                 report_status(PG_WARNING, "warning");
     122            0 :                 if (check_mode)
     123            0 :                         pg_log(PG_WARNING, "\n"
     124              :                                    "Your installation contains hash indexes.  These indexes have different\n"
     125              :                                    "internal formats between your old and new clusters, so they must be\n"
     126              :                                    "reindexed with the REINDEX command.  After upgrading, you will be given\n"
     127              :                                    "REINDEX instructions.");
     128              :                 else
     129            0 :                         pg_log(PG_WARNING, "\n"
     130              :                                    "Your installation contains hash indexes.  These indexes have different\n"
     131              :                                    "internal formats between your old and new clusters, so they must be\n"
     132              :                                    "reindexed with the REINDEX command.  The file\n"
     133              :                                    "    %s\n"
     134              :                                    "when executed by psql by the database superuser will recreate all invalid\n"
     135              :                                    "indexes; until then, none of these indexes will be used.",
     136            0 :                                    output_path);
     137            0 :         }
     138              :         else
     139            0 :                 check_ok();
     140            0 : }
     141              : 
     142              : /*
     143              :  * Callback function for processing results of query for
     144              :  * report_extension_updates()'s UpgradeTask.  If the query returned any rows,
     145              :  * write the details to the report file.
     146              :  */
     147              : static void
     148            0 : process_extension_updates(DbInfo *dbinfo, PGresult *res, void *arg)
     149              : {
     150            0 :         int                     ntups = PQntuples(res);
     151            0 :         int                     i_name = PQfnumber(res, "name");
     152            0 :         UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
     153            0 :         PQExpBufferData connectbuf;
     154              : 
     155            0 :         if (ntups == 0)
     156            0 :                 return;
     157              : 
     158            0 :         if (report->file == NULL &&
     159            0 :                 (report->file = fopen_priv(report->path, "w")) == NULL)
     160            0 :                 pg_fatal("could not open file \"%s\": %m", report->path);
     161              : 
     162            0 :         initPQExpBuffer(&connectbuf);
     163            0 :         appendPsqlMetaConnect(&connectbuf, dbinfo->db_name);
     164            0 :         fputs(connectbuf.data, report->file);
     165            0 :         termPQExpBuffer(&connectbuf);
     166              : 
     167            0 :         for (int rowno = 0; rowno < ntups; rowno++)
     168            0 :                 fprintf(report->file, "ALTER EXTENSION %s UPDATE;\n",
     169            0 :                                 quote_identifier(PQgetvalue(res, rowno, i_name)));
     170            0 : }
     171              : 
     172              : /*
     173              :  * report_extension_updates()
     174              :  *      Report extensions that should be updated.
     175              :  */
     176              : void
     177            0 : report_extension_updates(ClusterInfo *cluster)
     178              : {
     179            0 :         UpgradeTaskReport report;
     180            0 :         UpgradeTask *task = upgrade_task_create();
     181            0 :         const char *query = "SELECT name "
     182              :                 "FROM pg_available_extensions "
     183              :                 "WHERE installed_version != default_version";
     184              : 
     185            0 :         prep_status("Checking for extension updates");
     186              : 
     187            0 :         report.file = NULL;
     188            0 :         strcpy(report.path, "update_extensions.sql");
     189              : 
     190            0 :         upgrade_task_add_step(task, query, process_extension_updates,
     191              :                                                   true, &report);
     192              : 
     193            0 :         upgrade_task_run(task, cluster);
     194            0 :         upgrade_task_free(task);
     195              : 
     196            0 :         if (report.file)
     197              :         {
     198            0 :                 fclose(report.file);
     199            0 :                 report_status(PG_REPORT, "notice");
     200            0 :                 pg_log(PG_REPORT, "\n"
     201              :                            "Your installation contains extensions that should be updated\n"
     202              :                            "with the ALTER EXTENSION command.  The file\n"
     203              :                            "    %s\n"
     204              :                            "when executed by psql by the database superuser will update\n"
     205              :                            "these extensions.",
     206            0 :                            report.path);
     207            0 :         }
     208              :         else
     209            0 :                 check_ok();
     210            0 : }
        

Generated by: LCOV version 2.3.2-1