LCOV - differential code coverage report
Current view: top level - src/bin/scripts - common.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 68.1 % 47 32 15 32
Current Date: 2024-04-14 14:21:10 Functions: 66.7 % 3 2 1 2
Baseline: 16@8cea358b128 Branches: 72.2 % 18 13 5 13
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 68.1 % 47 32 15 32
Function coverage date bins:
(240..) days: 66.7 % 3 2 1 2
Branch coverage date bins:
(240..) days: 72.2 % 18 13 5 13

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  *  common.c
                                  4                 :                :  *      Common support routines for bin/scripts/
                                  5                 :                :  *
                                  6                 :                :  *
                                  7                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  * src/bin/scripts/common.c
                                 11                 :                :  *
                                 12                 :                :  *-------------------------------------------------------------------------
                                 13                 :                :  */
                                 14                 :                : 
                                 15                 :                : #include "postgres_fe.h"
                                 16                 :                : 
                                 17                 :                : #include <signal.h>
                                 18                 :                : #include <unistd.h>
                                 19                 :                : 
                                 20                 :                : #include "common.h"
                                 21                 :                : #include "common/connect.h"
                                 22                 :                : #include "common/logging.h"
                                 23                 :                : #include "common/string.h"
                                 24                 :                : #include "fe_utils/cancel.h"
                                 25                 :                : #include "fe_utils/query_utils.h"
                                 26                 :                : #include "fe_utils/string_utils.h"
                                 27                 :                : 
                                 28                 :                : /*
                                 29                 :                :  * Split TABLE[(COLUMNS)] into TABLE and [(COLUMNS)] portions.  When you
                                 30                 :                :  * finish using them, pg_free(*table).  *columns is a pointer into "spec",
                                 31                 :                :  * possibly to its NUL terminator.
                                 32                 :                :  */
                                 33                 :                : void
 1902 michael@paquier.xyz        34                 :CBC          49 : splitTableColumnsSpec(const char *spec, int encoding,
                                 35                 :                :                       char **table, const char **columns)
                                 36                 :                : {
 2239 noah@leadboat.com          37                 :             49 :     bool        inquotes = false;
                                 38                 :             49 :     const char *cp = spec;
                                 39                 :                : 
                                 40                 :                :     /*
                                 41                 :                :      * Find the first '(' not identifier-quoted.  Based on
                                 42                 :                :      * dequote_downcase_identifier().
                                 43                 :                :      */
                                 44   [ +  +  +  +  :            559 :     while (*cp && (*cp != '(' || inquotes))
                                              +  + ]
                                 45                 :                :     {
                                 46         [ +  + ]:            510 :         if (*cp == '"')
                                 47                 :                :         {
                                 48   [ +  +  +  + ]:              3 :             if (inquotes && cp[1] == '"')
                                 49                 :              1 :                 cp++;           /* pair does not affect quoting */
                                 50                 :                :             else
                                 51                 :              2 :                 inquotes = !inquotes;
                                 52                 :              3 :             cp++;
                                 53                 :                :         }
                                 54                 :                :         else
 1042 tgl@sss.pgh.pa.us          55                 :            507 :             cp += PQmblenBounded(cp, encoding);
                                 56                 :                :     }
 1593 alvherre@alvh.no-ip.       57                 :             49 :     *table = pnstrdup(spec, cp - spec);
 2239 noah@leadboat.com          58                 :             49 :     *columns = cp;
                                 59                 :             49 : }
                                 60                 :                : 
                                 61                 :                : /*
                                 62                 :                :  * Break apart TABLE[(COLUMNS)] of "spec".  With the reset_val of search_path
                                 63                 :                :  * in effect, have regclassin() interpret the TABLE portion.  Append to "buf"
                                 64                 :                :  * the qualified name of TABLE, followed by any (COLUMNS).  Exit on failure.
                                 65                 :                :  * We use this to interpret --table=foo under the search path psql would get,
                                 66                 :                :  * in advance of "ANALYZE public.foo" under the always-secure search path.
                                 67                 :                :  */
                                 68                 :                : void
                                 69                 :             38 : appendQualifiedRelation(PQExpBuffer buf, const char *spec,
                                 70                 :                :                         PGconn *conn, bool echo)
                                 71                 :                : {
                                 72                 :                :     char       *table;
                                 73                 :                :     const char *columns;
                                 74                 :                :     PQExpBufferData sql;
                                 75                 :                :     PGresult   *res;
                                 76                 :                :     int         ntups;
                                 77                 :                : 
 1902 michael@paquier.xyz        78                 :             38 :     splitTableColumnsSpec(spec, PQclientEncoding(conn), &table, &columns);
                                 79                 :                : 
                                 80                 :                :     /*
                                 81                 :                :      * Query must remain ABSOLUTELY devoid of unqualified names.  This would
                                 82                 :                :      * be unnecessary given a regclassin() variant taking a search_path
                                 83                 :                :      * argument.
                                 84                 :                :      */
 2239 noah@leadboat.com          85                 :             38 :     initPQExpBuffer(&sql);
                                 86                 :             38 :     appendPQExpBufferStr(&sql,
                                 87                 :                :                          "SELECT c.relname, ns.nspname\n"
                                 88                 :                :                          " FROM pg_catalog.pg_class c,"
                                 89                 :                :                          " pg_catalog.pg_namespace ns\n"
                                 90                 :                :                          " WHERE c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
                                 91                 :                :                          "  AND c.oid OPERATOR(pg_catalog.=) ");
                                 92                 :             38 :     appendStringLiteralConn(&sql, table, conn);
                                 93                 :             38 :     appendPQExpBufferStr(&sql, "::pg_catalog.regclass;");
                                 94                 :                : 
 1731 michael@paquier.xyz        95                 :             38 :     executeCommand(conn, "RESET search_path;", echo);
                                 96                 :                : 
                                 97                 :                :     /*
                                 98                 :                :      * One row is a typical result, as is a nonexistent relation ERROR.
                                 99                 :                :      * regclassin() unconditionally accepts all-digits input as an OID; if no
                                100                 :                :      * relation has that OID; this query returns no rows.  Catalog corruption
                                101                 :                :      * might elicit other row counts.
                                102                 :                :      */
                                103                 :             38 :     res = executeQuery(conn, sql.data, echo);
 2239 noah@leadboat.com         104                 :             37 :     ntups = PQntuples(res);
                                105         [ -  + ]:             37 :     if (ntups != 1)
                                106                 :                :     {
 1840 peter@eisentraut.org      107                 :UBC           0 :         pg_log_error(ngettext("query returned %d row instead of one: %s",
                                108                 :                :                               "query returned %d rows instead of one: %s",
                                109                 :                :                               ntups),
                                110                 :                :                      ntups, sql.data);
 2239 noah@leadboat.com         111                 :              0 :         PQfinish(conn);
                                112                 :              0 :         exit(1);
                                113                 :                :     }
 2239 noah@leadboat.com         114                 :CBC          37 :     appendPQExpBufferStr(buf,
 2067 tgl@sss.pgh.pa.us         115                 :             37 :                          fmtQualifiedId(PQgetvalue(res, 0, 1),
 2239 noah@leadboat.com         116                 :             37 :                                         PQgetvalue(res, 0, 0)));
                                117                 :             37 :     appendPQExpBufferStr(buf, columns);
                                118                 :             37 :     PQclear(res);
                                119                 :             37 :     termPQExpBuffer(&sql);
                                120                 :             37 :     pg_free(table);
                                121                 :                : 
 1731 michael@paquier.xyz       122                 :             37 :     PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo));
 2239 noah@leadboat.com         123                 :             37 : }
                                124                 :                : 
                                125                 :                : 
                                126                 :                : /*
                                127                 :                :  * Check yes/no answer in a localized way.  1=yes, 0=no, -1=neither.
                                128                 :                :  */
                                129                 :                : 
                                130                 :                : /* translator: abbreviation for "yes" */
                                131                 :                : #define PG_YESLETTER gettext_noop("y")
                                132                 :                : /* translator: abbreviation for "no" */
                                133                 :                : #define PG_NOLETTER gettext_noop("n")
                                134                 :                : 
                                135                 :                : bool
 6414 peter_e@gmx.net           136                 :UBC           0 : yesno_prompt(const char *question)
                                137                 :                : {
                                138                 :                :     char        prompt[256];
                                139                 :                : 
                                140                 :                :     /*------
                                141                 :                :        translator: This is a question followed by the translated options for
                                142                 :                :        "yes" and "no". */
 6403 bruce@momjian.us          143                 :              0 :     snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
                                144                 :                :              _(question), _(PG_YESLETTER), _(PG_NOLETTER));
                                145                 :                : 
                                146                 :                :     for (;;)
 6414 peter_e@gmx.net           147                 :              0 :     {
                                148                 :                :         char       *resp;
                                149                 :                : 
 1319 tgl@sss.pgh.pa.us         150                 :              0 :         resp = simple_prompt(prompt, true);
                                151                 :                : 
 6414 peter_e@gmx.net           152         [ #  # ]:              0 :         if (strcmp(resp, _(PG_YESLETTER)) == 0)
                                153                 :                :         {
 1319 tgl@sss.pgh.pa.us         154                 :              0 :             free(resp);
 6414 peter_e@gmx.net           155                 :              0 :             return true;
                                156                 :                :         }
 2784 tgl@sss.pgh.pa.us         157         [ #  # ]:              0 :         if (strcmp(resp, _(PG_NOLETTER)) == 0)
                                158                 :                :         {
 1319                           159                 :              0 :             free(resp);
 6414 peter_e@gmx.net           160                 :              0 :             return false;
                                161                 :                :         }
 1319 tgl@sss.pgh.pa.us         162                 :              0 :         free(resp);
                                163                 :                : 
 6414                           164                 :              0 :         printf(_("Please answer \"%s\" or \"%s\".\n"),
                                165                 :                :                _(PG_YESLETTER), _(PG_NOLETTER));
                                166                 :                :     }
                                167                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622