LCOV - differential code coverage report
Current view: top level - src/bin/scripts - common.c (source / functions) Coverage Total Hit UIC GIC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 68.1 % 47 32 15 32
Current Date: 2025-09-06 07:49:51 +0900 Functions: 66.7 % 3 2 1 2
Baseline: lcov-20250906-005545-baseline Branches: 72.2 % 18 13 5 13
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 2 2 2
(360..) days: 66.7 % 45 30 15 30
Function coverage date bins:
(360..) days: 66.7 % 3 2 1 2
Branch coverage date bins:
(360..) 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-2025, 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/query_utils.h"
                                 25                 :                : #include "fe_utils/string_utils.h"
                                 26                 :                : 
                                 27                 :                : /*
                                 28                 :                :  * Split TABLE[(COLUMNS)] into TABLE and [(COLUMNS)] portions.  When you
                                 29                 :                :  * finish using them, pg_free(*table).  *columns is a pointer into "spec",
                                 30                 :                :  * possibly to its NUL terminator.
                                 31                 :                :  */
                                 32                 :                : void
 2412 michael@paquier.xyz        33                 :GIC          63 : splitTableColumnsSpec(const char *spec, int encoding,
                                 34                 :                :                       char **table, const char **columns)
                                 35                 :                : {
 2749 noah@leadboat.com          36                 :             63 :     bool        inquotes = false;
                                 37                 :             63 :     const char *cp = spec;
                                 38                 :                : 
                                 39                 :                :     /*
                                 40                 :                :      * Find the first '(' not identifier-quoted.  Based on
                                 41                 :                :      * dequote_downcase_identifier().
                                 42                 :                :      */
                                 43   [ +  +  +  +  :            865 :     while (*cp && (*cp != '(' || inquotes))
                                              +  + ]
                                 44                 :                :     {
                                 45         [ +  + ]:            802 :         if (*cp == '"')
                                 46                 :                :         {
                                 47   [ +  +  +  + ]:              3 :             if (inquotes && cp[1] == '"')
                                 48                 :              1 :                 cp++;           /* pair does not affect quoting */
                                 49                 :                :             else
                                 50                 :              2 :                 inquotes = !inquotes;
                                 51                 :              3 :             cp++;
                                 52                 :                :         }
                                 53                 :                :         else
 1552 tgl@sss.pgh.pa.us          54                 :            799 :             cp += PQmblenBounded(cp, encoding);
                                 55                 :                :     }
 2103 alvherre@alvh.no-ip.       56                 :             63 :     *table = pnstrdup(spec, cp - spec);
 2749 noah@leadboat.com          57                 :             63 :     *columns = cp;
                                 58                 :             63 : }
                                 59                 :                : 
                                 60                 :                : /*
                                 61                 :                :  * Break apart TABLE[(COLUMNS)] of "spec".  With the reset_val of search_path
                                 62                 :                :  * in effect, have regclassin() interpret the TABLE portion.  Append to "buf"
                                 63                 :                :  * the qualified name of TABLE, followed by any (COLUMNS).  Exit on failure.
                                 64                 :                :  * We use this to interpret --table=foo under the search path psql would get,
                                 65                 :                :  * in advance of "ANALYZE public.foo" under the always-secure search path.
                                 66                 :                :  */
                                 67                 :                : void
                                 68                 :             42 : appendQualifiedRelation(PQExpBuffer buf, const char *spec,
                                 69                 :                :                         PGconn *conn, bool echo)
                                 70                 :                : {
                                 71                 :                :     char       *table;
                                 72                 :                :     const char *columns;
                                 73                 :                :     PQExpBufferData sql;
                                 74                 :                :     PGresult   *res;
                                 75                 :                :     int         ntups;
                                 76                 :                : 
 2412 michael@paquier.xyz        77                 :             42 :     splitTableColumnsSpec(spec, PQclientEncoding(conn), &table, &columns);
                                 78                 :                : 
                                 79                 :                :     /*
                                 80                 :                :      * Query must remain ABSOLUTELY devoid of unqualified names.  This would
                                 81                 :                :      * be unnecessary given a regclassin() variant taking a search_path
                                 82                 :                :      * argument.
                                 83                 :                :      */
 2749 noah@leadboat.com          84                 :             42 :     initPQExpBuffer(&sql);
                                 85                 :             42 :     appendPQExpBufferStr(&sql,
                                 86                 :                :                          "SELECT c.relname, ns.nspname\n"
                                 87                 :                :                          " FROM pg_catalog.pg_class c,"
                                 88                 :                :                          " pg_catalog.pg_namespace ns\n"
                                 89                 :                :                          " WHERE c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
                                 90                 :                :                          "  AND c.oid OPERATOR(pg_catalog.=) ");
                                 91                 :             42 :     appendStringLiteralConn(&sql, table, conn);
                                 92                 :             42 :     appendPQExpBufferStr(&sql, "::pg_catalog.regclass;");
                                 93                 :                : 
 2241 michael@paquier.xyz        94                 :             42 :     executeCommand(conn, "RESET search_path;", echo);
                                 95                 :                : 
                                 96                 :                :     /*
                                 97                 :                :      * One row is a typical result, as is a nonexistent relation ERROR.
                                 98                 :                :      * regclassin() unconditionally accepts all-digits input as an OID; if no
                                 99                 :                :      * relation has that OID; this query returns no rows.  Catalog corruption
                                100                 :                :      * might elicit other row counts.
                                101                 :                :      */
                                102                 :             42 :     res = executeQuery(conn, sql.data, echo);
 2749 noah@leadboat.com         103                 :             41 :     ntups = PQntuples(res);
                                104         [ -  + ]:             41 :     if (ntups != 1)
                                105                 :                :     {
 2350 peter@eisentraut.org      106                 :UIC           0 :         pg_log_error(ngettext("query returned %d row instead of one: %s",
                                107                 :                :                               "query returned %d rows instead of one: %s",
                                108                 :                :                               ntups),
                                109                 :                :                      ntups, sql.data);
 2749 noah@leadboat.com         110                 :              0 :         PQfinish(conn);
                                111                 :              0 :         exit(1);
                                112                 :                :     }
 2749 noah@leadboat.com         113                 :GIC          82 :     appendPQExpBufferStr(buf,
  208 andres@anarazel.de        114                 :             41 :                          fmtQualifiedIdEnc(PQgetvalue(res, 0, 1),
                                115                 :             41 :                                            PQgetvalue(res, 0, 0),
                                116                 :                :                                            PQclientEncoding(conn)));
 2749 noah@leadboat.com         117                 :             41 :     appendPQExpBufferStr(buf, columns);
                                118                 :             41 :     PQclear(res);
                                119                 :             41 :     termPQExpBuffer(&sql);
                                120                 :             41 :     pg_free(table);
                                121                 :                : 
 2241 michael@paquier.xyz       122                 :             41 :     PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo));
 2749 noah@leadboat.com         123                 :             41 : }
                                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
 6924 peter_e@gmx.net           136                 :UIC           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". */
 6913 bruce@momjian.us          143                 :              0 :     snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
                                144                 :                :              _(question), _(PG_YESLETTER), _(PG_NOLETTER));
                                145                 :                : 
                                146                 :                :     for (;;)
 6924 peter_e@gmx.net           147                 :              0 :     {
                                148                 :                :         char       *resp;
                                149                 :                : 
 1829 tgl@sss.pgh.pa.us         150                 :              0 :         resp = simple_prompt(prompt, true);
                                151                 :                : 
 6924 peter_e@gmx.net           152         [ #  # ]:              0 :         if (strcmp(resp, _(PG_YESLETTER)) == 0)
                                153                 :                :         {
 1829 tgl@sss.pgh.pa.us         154                 :              0 :             free(resp);
 6924 peter_e@gmx.net           155                 :              0 :             return true;
                                156                 :                :         }
 3294 tgl@sss.pgh.pa.us         157         [ #  # ]:              0 :         if (strcmp(resp, _(PG_NOLETTER)) == 0)
                                158                 :                :         {
 1829                           159                 :              0 :             free(resp);
 6924 peter_e@gmx.net           160                 :              0 :             return false;
                                161                 :                :         }
 1829 tgl@sss.pgh.pa.us         162                 :              0 :         free(resp);
                                163                 :                : 
 6924                           164                 :              0 :         printf(_("Please answer \"%s\" or \"%s\".\n"),
                                165                 :                :                _(PG_YESLETTER), _(PG_NOLETTER));
                                166                 :                :     }
                                167                 :                : }
        

Generated by: LCOV version 2.4-beta