LCOV - code coverage report
Current view: top level - src/bin/pg_upgrade - version.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 21 76 27.6 %
Date: 2024-11-21 08:14:44 Functions: 3 4 75.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-2024, 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          12 : jsonb_9_4_check_applicable(ClusterInfo *cluster)
      22             : {
      23             :     /* JSONB changed its storage format during 9.4 beta */
      24          12 :     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          12 :     return false;
      29             : }
      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             :     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             :         PGresult   *res;
      49           0 :         bool        db_used = false;
      50             :         int         ntups;
      51             :         int         rowno;
      52             :         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             :                     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             :                 }
      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             :             }
      94             :         }
      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             :         }
     112             : 
     113           0 :         PQfinish(conn);
     114             :     }
     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             :                    output_path);
     137             :     }
     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          20 : process_extension_updates(DbInfo *dbinfo, PGresult *res, void *arg)
     149             : {
     150          20 :     int         ntups = PQntuples(res);
     151          20 :     int         i_name = PQfnumber(res, "name");
     152          20 :     UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
     153             :     PQExpBufferData connectbuf;
     154             : 
     155             :     AssertVariableIsOfType(&process_extension_updates, UpgradeTaskProcessCB);
     156             : 
     157          20 :     if (ntups == 0)
     158          20 :         return;
     159             : 
     160           0 :     if (report->file == NULL &&
     161           0 :         (report->file = fopen_priv(report->path, "w")) == NULL)
     162           0 :         pg_fatal("could not open file \"%s\": %m", report->path);
     163             : 
     164           0 :     initPQExpBuffer(&connectbuf);
     165           0 :     appendPsqlMetaConnect(&connectbuf, dbinfo->db_name);
     166           0 :     fputs(connectbuf.data, report->file);
     167           0 :     termPQExpBuffer(&connectbuf);
     168             : 
     169           0 :     for (int rowno = 0; rowno < ntups; rowno++)
     170           0 :         fprintf(report->file, "ALTER EXTENSION %s UPDATE;\n",
     171           0 :                 quote_identifier(PQgetvalue(res, rowno, i_name)));
     172             : }
     173             : 
     174             : /*
     175             :  * report_extension_updates()
     176             :  *  Report extensions that should be updated.
     177             :  */
     178             : void
     179           6 : report_extension_updates(ClusterInfo *cluster)
     180             : {
     181             :     UpgradeTaskReport report;
     182           6 :     UpgradeTask *task = upgrade_task_create();
     183           6 :     const char *query = "SELECT name "
     184             :         "FROM pg_available_extensions "
     185             :         "WHERE installed_version != default_version";
     186             : 
     187           6 :     prep_status("Checking for extension updates");
     188             : 
     189           6 :     report.file = NULL;
     190           6 :     strcpy(report.path, "update_extensions.sql");
     191             : 
     192           6 :     upgrade_task_add_step(task, query, process_extension_updates,
     193             :                           true, &report);
     194             : 
     195           6 :     upgrade_task_run(task, cluster);
     196           6 :     upgrade_task_free(task);
     197             : 
     198           6 :     if (report.file)
     199             :     {
     200           0 :         fclose(report.file);
     201           0 :         report_status(PG_REPORT, "notice");
     202           0 :         pg_log(PG_REPORT, "\n"
     203             :                "Your installation contains extensions that should be updated\n"
     204             :                "with the ALTER EXTENSION command.  The file\n"
     205             :                "    %s\n"
     206             :                "when executed by psql by the database superuser will update\n"
     207             :                "these extensions.",
     208             :                report.path);
     209             :     }
     210             :     else
     211           6 :         check_ok();
     212           6 : }

Generated by: LCOV version 1.14