LCOV - differential code coverage report
Current view: top level - src/bin/pg_upgrade - function.c (source / functions) Coverage Total Hit UNC UIC UBC GBC GIC GNC CBC EUB ECB DUB
Current: Differential Code Coverage HEAD vs 15 Lines: 82.4 % 68 56 2 5 5 1 11 2 42 4 14 2
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 3 3 1 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 100.0 % 1 1 1
Legend: Lines: hit not hit (180,240] days: 100.0 % 1 1 1
(240..) days: 81.8 % 66 54 2 5 5 1 11 42 4 14
Function coverage date bins:
(240..) days: 100.0 % 3 3 1 2

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  *  function.c
                                  3                 :  *
                                  4                 :  *  server-side function support
                                  5                 :  *
                                  6                 :  *  Copyright (c) 2010-2023, PostgreSQL Global Development Group
                                  7                 :  *  src/bin/pg_upgrade/function.c
                                  8                 :  */
                                  9                 : 
                                 10                 : #include "postgres_fe.h"
                                 11                 : 
                                 12                 : #include "access/transam.h"
                                 13                 : #include "catalog/pg_language_d.h"
                                 14                 : #include "pg_upgrade.h"
                                 15                 : 
                                 16                 : /*
                                 17                 :  * qsort comparator for pointers to library names
                                 18                 :  *
                                 19                 :  * We sort first by name length, then alphabetically for names of the
                                 20                 :  * same length, then database array index.  This is to ensure that, eg,
                                 21                 :  * "hstore_plpython" sorts after both "hstore" and "plpython"; otherwise
                                 22                 :  * transform modules will probably fail their LOAD tests.  (The backend
                                 23                 :  * ought to cope with that consideration, but it doesn't yet, and even
                                 24                 :  * when it does it'll still be a good idea to have a predictable order of
                                 25                 :  * probing here.)
                                 26                 :  */
                                 27                 : static int
 2379 tgl                        28 CBC           4 : library_name_compare(const void *p1, const void *p2)
                                 29                 : {
 1716 bruce                      30               4 :     const char *str1 = ((const LibraryInfo *) p1)->name;
                                 31               4 :     const char *str2 = ((const LibraryInfo *) p2)->name;
 2379 tgl                        32               4 :     int         slen1 = strlen(str1);
                                 33               4 :     int         slen2 = strlen(str2);
 1716 bruce                      34               4 :     int         cmp = strcmp(str1, str2);
                                 35                 : 
 2379 tgl                        36               4 :     if (slen1 != slen2)
                                 37               2 :         return slen1 - slen2;
 1716 bruce                      38               2 :     if (cmp != 0)
                                 39               2 :         return cmp;
                                 40                 :     else
 1716 bruce                      41 UBC           0 :         return ((const LibraryInfo *) p1)->dbnum -
 1418 tgl                        42               0 :             ((const LibraryInfo *) p2)->dbnum;
                                 43                 : }
                                 44                 : 
                                 45                 : 
                                 46                 : /*
                                 47                 :  * get_loadable_libraries()
                                 48                 :  *
                                 49                 :  *  Fetch the names of all old libraries containing C-language functions.
                                 50                 :  *  We will later check that they all exist in the new installation.
                                 51                 :  */
                                 52                 : void
 4555 bruce                      53 CBC           2 : get_loadable_libraries(void)
                                 54                 : {
                                 55                 :     PGresult  **ress;
                                 56                 :     int         totaltups;
                                 57                 :     int         dbnum;
                                 58                 : 
 4177                            59               2 :     ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
 4715                            60               2 :     totaltups = 0;
                                 61                 : 
                                 62                 :     /* Fetch all library names, removing duplicates within each DB */
 4481                            63              14 :     for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
                                 64                 :     {
                                 65              12 :         DbInfo     *active_db = &old_cluster.dbarr.dbs[dbnum];
                                 66              12 :         PGconn     *conn = connectToServer(&old_cluster, active_db->db_name);
                                 67                 : 
                                 68                 :         /*
                                 69                 :          * Fetch all libraries containing non-built-in C functions in this DB.
                                 70                 :          */
 4555                            71              12 :         ress[dbnum] = executeQueryOrDie(conn,
                                 72                 :                                         "SELECT DISTINCT probin "
                                 73                 :                                         "FROM pg_catalog.pg_proc "
                                 74                 :                                         "WHERE prolang = %u AND "
                                 75                 :                                         "probin IS NOT NULL AND "
                                 76                 :                                         "oid >= %u;",
                                 77                 :                                         ClanguageId,
                                 78                 :                                         FirstNormalObjectId);
 4715                            79              12 :         totaltups += PQntuples(ress[dbnum]);
                                 80                 : 
                                 81              12 :         PQfinish(conn);
                                 82                 :     }
                                 83                 : 
 1716                            84               2 :     os_info.libraries = (LibraryInfo *) pg_malloc(totaltups * sizeof(LibraryInfo));
 4715                            85               2 :     totaltups = 0;
                                 86                 : 
 4481                            87              14 :     for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
                                 88                 :     {
 4715                            89              12 :         PGresult   *res = ress[dbnum];
                                 90                 :         int         ntups;
                                 91                 :         int         rowno;
                                 92                 : 
                                 93              12 :         ntups = PQntuples(res);
                                 94              18 :         for (rowno = 0; rowno < ntups; rowno++)
                                 95                 :         {
                                 96               6 :             char       *lib = PQgetvalue(res, rowno, 0);
                                 97                 : 
 1716                            98               6 :             os_info.libraries[totaltups].name = pg_strdup(lib);
                                 99               6 :             os_info.libraries[totaltups].dbnum = dbnum;
                                100                 : 
                                101               6 :             totaltups++;
                                102                 :         }
 4715                           103              12 :         PQclear(res);
                                104                 :     }
                                105                 : 
                                106               2 :     pg_free(ress);
                                107                 : 
 2379 tgl                       108               2 :     os_info.num_libraries = totaltups;
 4715 bruce                     109               2 : }
                                110                 : 
                                111                 : 
                                112                 : /*
                                113                 :  * check_loadable_libraries()
                                114                 :  *
                                115                 :  *  Check that the new cluster contains all required libraries.
                                116                 :  *  We do this by actually trying to LOAD each one, thereby testing
                                117                 :  *  compatibility as well as presence.
                                118                 :  */
                                119                 : void
 4555                           120               2 : check_loadable_libraries(void)
                                121                 : {
 4481                           122               2 :     PGconn     *conn = connectToServer(&new_cluster, "template1");
                                123                 :     int         libnum;
 1716                           124               2 :     int         was_load_failure = false;
 4715                           125               2 :     FILE       *script = NULL;
                                126                 :     char        output_path[MAXPGPATH];
 4715 bruce                     127 ECB             : 
 4555 bruce                     128 GIC           2 :     prep_status("Checking for presence of required libraries");
 4715 bruce                     129 ECB             : 
  427 michael                   130 GIC           2 :     snprintf(output_path, sizeof(output_path), "%s/%s",
                                131                 :              log_opts.basedir, "loadable_libraries.txt");
                                132                 : 
                                133                 :     /*
                                134                 :      * Now we want to sort the library names into order.  This avoids multiple
                                135                 :      * probes of the same library, and ensures that libraries are probed in a
                                136                 :      * consistent order, which is important for reproducible behavior if one
                                137                 :      * library depends on another.
 1716 bruce                     138 ECB             :      */
   61 peter                     139 GNC           2 :     qsort(os_info.libraries, os_info.num_libraries,
                                140                 :           sizeof(LibraryInfo), library_name_compare);
 1716 bruce                     141 ECB             : 
 4555 bruce                     142 GIC           8 :     for (libnum = 0; libnum < os_info.num_libraries; libnum++)
 4715 bruce                     143 ECB             :     {
 1716 bruce                     144 CBC           6 :         char       *lib = os_info.libraries[libnum].name;
 4715 bruce                     145 GIC           6 :         int         llen = strlen(lib);
                                146                 :         char        cmd[7 + 2 * MAXPGPATH + 1];
                                147                 :         PGresult   *res;
                                148                 : 
 1716 bruce                     149 ECB             :         /* Did the library name change?  Probe it. */
 1716 bruce                     150 GIC           6 :         if (libnum == 0 || strcmp(lib, os_info.libraries[libnum - 1].name) != 0)
 4715 bruce                     151 ECB             :         {
 1716 bruce                     152 CBC           6 :             strcpy(cmd, "LOAD '");
                                153               6 :             PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL);
 1716 bruce                     154 GIC           6 :             strcat(cmd, "'");
 1536 peter                     155 ECB             : 
 1716 bruce                     156 GIC           6 :             res = PQexec(conn, cmd);
 1536 peter                     157 ECB             : 
 1716 bruce                     158 GIC           6 :             if (PQresultStatus(res) != PGRES_COMMAND_OK)
 1716 bruce                     159 EUB             :             {
 1716 bruce                     160 UBC           0 :                 was_load_failure = true;
 1536 peter                     161 EUB             : 
 1716 bruce                     162 UBC           0 :                 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  271 tgl                       163 UNC           0 :                     pg_fatal("could not open file \"%s\": %s",
 1716 bruce                     164 UIC           0 :                              output_path, strerror(errno));
                                165               0 :                 fprintf(script, _("could not load library \"%s\": %s"),
                                166                 :                         lib,
                                167                 :                         PQerrorMessage(conn));
 1716 bruce                     168 ECB             :             }
                                169                 :             else
 1716 bruce                     170 CBC           6 :                 was_load_failure = false;
                                171                 : 
 1716 bruce                     172 GIC           6 :             PQclear(res);
 4715 bruce                     173 ECB             :         }
 4715 bruce                     174 EUB             : 
 1716 bruce                     175 GBC           6 :         if (was_load_failure)
 1279 bruce                     176 UIC           0 :             fprintf(script, _("In database: %s\n"),
 1418 tgl                       177               0 :                     old_cluster.dbarr.dbs[os_info.libraries[libnum].dbnum].db_name);
 4715 bruce                     178 ECB             :     }
                                179                 : 
 4715 bruce                     180 CBC           2 :     PQfinish(conn);
                                181                 : 
  221 dgustafsson               182 GNC           2 :     if (script)
 4715 bruce                     183 EUB             :     {
 4715 bruce                     184 UBC           0 :         fclose(script);
  271 tgl                       185 UNC           0 :         pg_log(PG_REPORT, "fatal");
 3477 peter_e                   186 UIC           0 :         pg_fatal("Your installation references loadable libraries that are missing from the\n"
                                187                 :                  "new installation.  You can add these libraries to the new installation,\n"
                                188                 :                  "or remove the functions using them from the old installation.  A list of\n"
                                189                 :                  "problem libraries is in the file:\n"
                                190                 :                  "    %s", output_path);
 4715 bruce                     191 ECB             :     }
                                192                 :     else
 4555 bruce                     193 GIC           2 :         check_ok();
 4715                           194               2 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a