LCOV - differential code coverage report
Current view: top level - src/common - compression.c (source / functions) Coverage Total Hit UBC CBC
Current: ba12a202ce1b5581dc0ed149cf3f637d7897ad5d vs 2866d8c7dbfc9d882a7d80fef93fbbe763709932 Lines: 83.6 % 189 158 31 158
Current Date: 2026-08-27 14:31:44 +0300 Functions: 100.0 % 8 8 8
Baseline: lcov-20260827-baseline Branches: 76.4 % 127 97 30 97
Baseline Date: 2026-08-27 14:31:58 +0300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 71.4 % 7 5 2 5
(30,360] days: 87.5 % 16 14 2 14
(360..) days: 83.7 % 166 139 27 139
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 7 7 7
Branch coverage date bins:
(30,360] days: 90.0 % 20 18 2 18
(360..) days: 73.8 % 107 79 28 79

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * compression.c
                                  4                 :                :  *
                                  5                 :                :  * Shared code for compression methods and specifications.
                                  6                 :                :  *
                                  7                 :                :  * A compression specification specifies the parameters that should be used
                                  8                 :                :  * when performing compression with a specific algorithm. The simplest
                                  9                 :                :  * possible compression specification is an integer, which sets the
                                 10                 :                :  * compression level.
                                 11                 :                :  *
                                 12                 :                :  * Otherwise, a compression specification is a comma-separated list of items,
                                 13                 :                :  * each having the form keyword or keyword=value.
                                 14                 :                :  *
                                 15                 :                :  * Currently, the supported keywords are "level", "long", and "workers".
                                 16                 :                :  *
                                 17                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                 18                 :                :  *
                                 19                 :                :  * IDENTIFICATION
                                 20                 :                :  *        src/common/compression.c
                                 21                 :                :  *-------------------------------------------------------------------------
                                 22                 :                :  */
                                 23                 :                : 
                                 24                 :                : #ifndef FRONTEND
                                 25                 :                : #include "postgres.h"
                                 26                 :                : #else
                                 27                 :                : #include "postgres_fe.h"
                                 28                 :                : #endif
                                 29                 :                : 
                                 30                 :                : #ifdef USE_ZSTD
                                 31                 :                : #include <zstd.h>
                                 32                 :                : #endif
                                 33                 :                : #ifdef HAVE_LIBZ
                                 34                 :                : #include <zlib.h>
                                 35                 :                : #endif
                                 36                 :                : 
                                 37                 :                : #include "common/compression.h"
                                 38                 :                : 
                                 39                 :                : static int  expect_integer_value(char *keyword, char *value,
                                 40                 :                :                                  pg_compress_specification *result);
                                 41                 :                : static bool expect_boolean_value(char *keyword, char *value,
                                 42                 :                :                                  pg_compress_specification *result);
                                 43                 :                : 
                                 44                 :                : /*
                                 45                 :                :  * Look up a compression algorithm by archive file extension. Sets *algorithm
                                 46                 :                :  * and returns the length of the non-extension portion of the filename, or -1
                                 47                 :                :  * if the filename does not end with a recognized tar extension.
                                 48                 :                :  */
                                 49                 :                : int
  160 andrew@dunslane.net        50                 :CBC         387 : parse_tar_compress_algorithm(const char *fname, pg_compress_algorithm *algorithm)
                                 51                 :                : {
   24 rhaas@postgresql.org       52                 :            387 :     int         fname_len = strlen(fname);
                                 53                 :                : 
  160 andrew@dunslane.net        54         [ +  + ]:            387 :     if (fname_len >= 4 &&
                                 55         [ +  + ]:            386 :         strcmp(fname + fname_len - 4, ".tar") == 0)
                                 56                 :                :     {
                                 57                 :            280 :         *algorithm = PG_COMPRESSION_NONE;
   24 rhaas@postgresql.org       58                 :            280 :         return fname_len - 4;
                                 59                 :                :     }
  160 andrew@dunslane.net        60         [ +  + ]:            107 :     else if (fname_len >= 4 &&
                                 61         [ -  + ]:            106 :              strcmp(fname + fname_len - 4, ".tgz") == 0)
                                 62                 :                :     {
  160 andrew@dunslane.net        63                 :UBC           0 :         *algorithm = PG_COMPRESSION_GZIP;
   24 rhaas@postgresql.org       64                 :              0 :         return fname_len - 4;
                                 65                 :                :     }
  160 andrew@dunslane.net        66         [ +  + ]:CBC         107 :     else if (fname_len >= 7 &&
                                 67         [ +  + ]:            106 :              strcmp(fname + fname_len - 7, ".tar.gz") == 0)
                                 68                 :                :     {
                                 69                 :             22 :         *algorithm = PG_COMPRESSION_GZIP;
   24 rhaas@postgresql.org       70                 :             22 :         return fname_len - 7;
                                 71                 :                :     }
  160 andrew@dunslane.net        72         [ +  + ]:             85 :     else if (fname_len >= 8 &&
                                 73         [ +  + ]:             84 :              strcmp(fname + fname_len - 8, ".tar.lz4") == 0)
                                 74                 :                :     {
                                 75                 :             11 :         *algorithm = PG_COMPRESSION_LZ4;
   24 rhaas@postgresql.org       76                 :             11 :         return fname_len - 8;
                                 77                 :                :     }
  160 andrew@dunslane.net        78         [ +  + ]:             74 :     else if (fname_len >= 8 &&
                                 79         [ -  + ]:             73 :              strcmp(fname + fname_len - 8, ".tar.zst") == 0)
                                 80                 :                :     {
  160 andrew@dunslane.net        81                 :UBC           0 :         *algorithm = PG_COMPRESSION_ZSTD;
   24 rhaas@postgresql.org       82                 :              0 :         return fname_len - 8;
                                 83                 :                :     }
                                 84                 :                : 
   24 rhaas@postgresql.org       85                 :CBC          74 :     return -1;
                                 86                 :                : }
                                 87                 :                : 
                                 88                 :                : /*
                                 89                 :                :  * Look up a compression algorithm by name. Returns true and sets *algorithm
                                 90                 :                :  * if the name is recognized. Otherwise returns false.
                                 91                 :                :  */
                                 92                 :                : bool
 1598 michael@paquier.xyz        93                 :            452 : parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
                                 94                 :                : {
 1618 rhaas@postgresql.org       95         [ +  + ]:            452 :     if (strcmp(name, "none") == 0)
 1598 michael@paquier.xyz        96                 :            350 :         *algorithm = PG_COMPRESSION_NONE;
 1618 rhaas@postgresql.org       97         [ +  + ]:            102 :     else if (strcmp(name, "gzip") == 0)
 1598 michael@paquier.xyz        98                 :             89 :         *algorithm = PG_COMPRESSION_GZIP;
 1618 rhaas@postgresql.org       99         [ +  + ]:             13 :     else if (strcmp(name, "lz4") == 0)
 1598 michael@paquier.xyz       100                 :              9 :         *algorithm = PG_COMPRESSION_LZ4;
 1618 rhaas@postgresql.org      101         [ -  + ]:              4 :     else if (strcmp(name, "zstd") == 0)
 1598 michael@paquier.xyz       102                 :UBC           0 :         *algorithm = PG_COMPRESSION_ZSTD;
                                103                 :                :     else
 1618 rhaas@postgresql.org      104                 :CBC           4 :         return false;
                                105                 :            448 :     return true;
                                106                 :                : }
                                107                 :                : 
                                108                 :                : /*
                                109                 :                :  * Get the human-readable name corresponding to a particular compression
                                110                 :                :  * algorithm.
                                111                 :                :  */
                                112                 :                : const char *
 1598 michael@paquier.xyz       113                 :             14 : get_compress_algorithm_name(pg_compress_algorithm algorithm)
                                114                 :                : {
 1618 rhaas@postgresql.org      115   [ +  +  +  -  :             14 :     switch (algorithm)
                                                 - ]
                                116                 :                :     {
 1598 michael@paquier.xyz       117                 :              3 :         case PG_COMPRESSION_NONE:
 1618 rhaas@postgresql.org      118                 :              3 :             return "none";
 1598 michael@paquier.xyz       119                 :             10 :         case PG_COMPRESSION_GZIP:
 1618 rhaas@postgresql.org      120                 :             10 :             return "gzip";
 1598 michael@paquier.xyz       121                 :              1 :         case PG_COMPRESSION_LZ4:
 1618 rhaas@postgresql.org      122                 :              1 :             return "lz4";
 1598 michael@paquier.xyz       123                 :UBC           0 :         case PG_COMPRESSION_ZSTD:
 1618 rhaas@postgresql.org      124                 :              0 :             return "zstd";
                                125                 :                :             /* no default, to provoke compiler warnings if values are added */
                                126                 :                :     }
                                127                 :              0 :     Assert(false);
                                128                 :                :     return "???";             /* placate compiler */
                                129                 :                : }
                                130                 :                : 
                                131                 :                : /*
                                132                 :                :  * Parse a compression specification for a specified algorithm.
                                133                 :                :  *
                                134                 :                :  * See the file header comments for a brief description of what a compression
                                135                 :                :  * specification is expected to look like.
                                136                 :                :  *
                                137                 :                :  * On return, all fields of the result object will be initialized.
                                138                 :                :  * In particular, result->parse_error will be NULL if no errors occurred
                                139                 :                :  * during parsing, and will otherwise contain an appropriate error message.
                                140                 :                :  * The caller may free this error message string using pfree, if desired.
                                141                 :                :  * Note, however, even if there's no parse error, the string might not make
                                142                 :                :  * sense: e.g. for gzip, level=12 is not sensible, but it does parse OK.
                                143                 :                :  *
                                144                 :                :  * The compression level is assigned by default if not directly specified
                                145                 :                :  * by the specification.
                                146                 :                :  *
                                147                 :                :  * Use validate_compress_specification() to find out whether a compression
                                148                 :                :  * specification is semantically sensible.
                                149                 :                :  */
                                150                 :                : void
 1598 michael@paquier.xyz       151                 :CBC         446 : parse_compress_specification(pg_compress_algorithm algorithm, char *specification,
                                152                 :                :                              pg_compress_specification *result)
                                153                 :                : {
                                154                 :                :     int         bare_level;
                                155                 :                :     char       *bare_level_endp;
                                156                 :                : 
                                157                 :                :     /* Initial setup of result object. */
 1618 rhaas@postgresql.org      158                 :            446 :     result->algorithm = algorithm;
                                159                 :            446 :     result->options = 0;
                                160                 :            446 :     result->parse_error = NULL;
                                161                 :                : 
                                162                 :                :     /*
                                163                 :                :      * Assign a default level depending on the compression method.  This may
                                164                 :                :      * be enforced later.
                                165                 :                :      */
 1443 michael@paquier.xyz       166   [ +  +  -  +  :            446 :     switch (result->algorithm)
                                                 - ]
                                167                 :                :     {
                                168                 :            348 :         case PG_COMPRESSION_NONE:
                                169                 :            348 :             result->level = 0;
                                170                 :            348 :             break;
                                171                 :              9 :         case PG_COMPRESSION_LZ4:
                                172                 :                : #ifdef USE_LZ4
                                173                 :              9 :             result->level = 0;   /* fast compression mode */
                                174                 :                : #else
                                175                 :                :             result->parse_error =
                                176                 :                :                 psprintf(_("this build does not support compression with %s"),
                                177                 :                :                          "LZ4");
                                178                 :                : #endif
                                179                 :              9 :             break;
 1443 michael@paquier.xyz       180                 :UBC           0 :         case PG_COMPRESSION_ZSTD:
                                181                 :                : #ifdef USE_ZSTD
                                182                 :                :             result->level = ZSTD_CLEVEL_DEFAULT;
                                183                 :                : #else
                                184                 :              0 :             result->parse_error =
                                185                 :              0 :                 psprintf(_("this build does not support compression with %s"),
                                186                 :                :                          "ZSTD");
                                187                 :                : #endif
                                188                 :              0 :             break;
 1443 michael@paquier.xyz       189                 :CBC          89 :         case PG_COMPRESSION_GZIP:
                                190                 :                : #ifdef HAVE_LIBZ
                                191                 :             89 :             result->level = Z_DEFAULT_COMPRESSION;
                                192                 :                : #else
                                193                 :                :             result->parse_error =
                                194                 :                :                 psprintf(_("this build does not support compression with %s"),
                                195                 :                :                          "gzip");
                                196                 :                : #endif
                                197                 :             89 :             break;
                                198                 :                :     }
                                199                 :                : 
                                200                 :                :     /* If there is no specification, we're done already. */
 1618 rhaas@postgresql.org      201         [ +  + ]:            446 :     if (specification == NULL)
                                202                 :            427 :         return;
                                203                 :                : 
                                204                 :                :     /* As a special case, the specification can be a bare integer. */
                                205                 :             38 :     bare_level = strtol(specification, &bare_level_endp, 10);
                                206   [ +  +  -  + ]:             38 :     if (specification != bare_level_endp && *bare_level_endp == '\0')
                                207                 :                :     {
                                208                 :             19 :         result->level = bare_level;
                                209                 :             19 :         return;
                                210                 :                :     }
                                211                 :                : 
                                212                 :                :     /* Look for comma-separated keyword or keyword=value entries. */
                                213                 :                :     while (1)
                                214                 :              2 :     {
                                215                 :                :         char       *kwstart;
                                216                 :                :         char       *kwend;
                                217                 :                :         char       *vstart;
                                218                 :                :         char       *vend;
                                219                 :                :         int         kwlen;
                                220                 :                :         int         vlen;
                                221                 :                :         bool        has_value;
                                222                 :                :         char       *keyword;
                                223                 :                :         char       *value;
                                224                 :                : 
                                225                 :                :         /* Figure start, end, and length of next keyword and any value. */
                                226                 :             21 :         kwstart = kwend = specification;
                                227   [ +  +  +  -  :            109 :         while (*kwend != '\0' && *kwend != ',' && *kwend != '=')
                                              +  + ]
                                228                 :             88 :             ++kwend;
                                229                 :             21 :         kwlen = kwend - kwstart;
                                230         [ +  + ]:             21 :         if (*kwend != '=')
                                231                 :                :         {
                                232                 :             11 :             vstart = vend = NULL;
                                233                 :             11 :             vlen = 0;
                                234                 :             11 :             has_value = false;
                                235                 :                :         }
                                236                 :                :         else
                                237                 :                :         {
                                238                 :             10 :             vstart = vend = kwend + 1;
                                239   [ +  +  +  + ]:             28 :             while (*vend != '\0' && *vend != ',')
                                240                 :             18 :                 ++vend;
                                241                 :             10 :             vlen = vend - vstart;
                                242                 :             10 :             has_value = true;
                                243                 :                :         }
                                244                 :                : 
                                245                 :                :         /* Reject empty keyword. */
                                246         [ +  + ]:             21 :         if (kwlen == 0)
                                247                 :                :         {
                                248                 :              4 :             result->parse_error =
                                249                 :              4 :                 pstrdup(_("found empty string where a compression option was expected"));
                                250                 :              4 :             break;
                                251                 :                :         }
                                252                 :                : 
                                253                 :                :         /* Extract keyword and value as separate C strings. */
                                254                 :             17 :         keyword = palloc(kwlen + 1);
                                255                 :             17 :         memcpy(keyword, kwstart, kwlen);
                                256                 :             17 :         keyword[kwlen] = '\0';
                                257         [ +  + ]:             17 :         if (!has_value)
                                258                 :              7 :             value = NULL;
                                259                 :                :         else
                                260                 :                :         {
                                261                 :             10 :             value = palloc(vlen + 1);
                                262                 :             10 :             memcpy(value, vstart, vlen);
                                263                 :             10 :             value[vlen] = '\0';
                                264                 :                :         }
                                265                 :                : 
                                266                 :                :         /* Handle whatever keyword we found. */
                                267         [ +  + ]:             17 :         if (strcmp(keyword, "level") == 0)
                                268                 :                :         {
                                269                 :             10 :             result->level = expect_integer_value(keyword, value, result);
                                270                 :                : 
                                271                 :                :             /*
                                272                 :                :              * No need to set a flag in "options", there is a default level
                                273                 :                :              * set at least thanks to the logic above.
                                274                 :                :              */
                                275                 :                :         }
 1611                           276         [ +  + ]:              7 :         else if (strcmp(keyword, "workers") == 0)
                                277                 :                :         {
                                278                 :              2 :             result->workers = expect_integer_value(keyword, value, result);
 1598 michael@paquier.xyz       279                 :              2 :             result->options |= PG_COMPRESSION_OPTION_WORKERS;
                                280                 :                :         }
 1239 tomas.vondra@postgre      281         [ +  + ]:              5 :         else if (strcmp(keyword, "long") == 0)
                                282                 :                :         {
                                283                 :              2 :             result->long_distance = expect_boolean_value(keyword, value, result);
                                284                 :              2 :             result->options |= PG_COMPRESSION_OPTION_LONG_DISTANCE;
                                285                 :                :         }
                                286                 :                :         else
 1618 rhaas@postgresql.org      287                 :              3 :             result->parse_error =
 1433 peter@eisentraut.org      288                 :              3 :                 psprintf(_("unrecognized compression option: \"%s\""), keyword);
                                289                 :                : 
                                290                 :                :         /* Release memory, just to be tidy. */
 1618 rhaas@postgresql.org      291                 :             17 :         pfree(keyword);
                                292         [ +  + ]:             17 :         if (value != NULL)
                                293                 :             10 :             pfree(value);
                                294                 :                : 
                                295                 :                :         /*
                                296                 :                :          * If we got an error or have reached the end of the string, stop.
                                297                 :                :          *
                                298                 :                :          * If there is no value, then the end of the keyword might have been
                                299                 :                :          * the end of the string. If there is a value, then the end of the
                                300                 :                :          * keyword cannot have been the end of the string, but the end of the
                                301                 :                :          * value might have been.
                                302                 :                :          */
 1611                           303   [ +  +  +  + ]:             17 :         if (result->parse_error != NULL ||
                                304   [ -  +  +  + ]:              8 :             (vend == NULL ? *kwend == '\0' : *vend == '\0'))
                                305                 :                :             break;
                                306                 :                : 
                                307                 :                :         /* Advance to next entry and loop around. */
 1618                           308         [ -  + ]:              2 :         specification = vend == NULL ? kwend + 1 : vend + 1;
                                309                 :                :     }
                                310                 :                : }
                                311                 :                : 
                                312                 :                : /*
                                313                 :                :  * Parse 'value' as an integer and return the result.
                                314                 :                :  *
                                315                 :                :  * If parsing fails, set result->parse_error to an appropriate message
                                316                 :                :  * and return -1.
                                317                 :                :  */
                                318                 :                : static int
 1598 michael@paquier.xyz       319                 :             12 : expect_integer_value(char *keyword, char *value, pg_compress_specification *result)
                                320                 :                : {
                                321                 :                :     int         ivalue;
                                322                 :                :     char       *ivalue_endp;
                                323                 :                : 
 1618 rhaas@postgresql.org      324         [ +  + ]:             12 :     if (value == NULL)
                                325                 :                :     {
                                326                 :              2 :         result->parse_error =
                                327                 :              2 :             psprintf(_("compression option \"%s\" requires a value"),
                                328                 :                :                      keyword);
                                329                 :              2 :         return -1;
                                330                 :                :     }
                                331                 :                : 
                                332                 :             10 :     ivalue = strtol(value, &ivalue_endp, 10);
                                333   [ +  +  -  + ]:             10 :     if (ivalue_endp == value || *ivalue_endp != '\0')
                                334                 :                :     {
                                335                 :              4 :         result->parse_error =
                                336                 :              4 :             psprintf(_("value for compression option \"%s\" must be an integer"),
                                337                 :                :                      keyword);
                                338                 :              4 :         return -1;
                                339                 :                :     }
                                340                 :              6 :     return ivalue;
                                341                 :                : }
                                342                 :                : 
                                343                 :                : /*
                                344                 :                :  * Parse 'value' as a boolean and return the result.
                                345                 :                :  *
                                346                 :                :  * If parsing fails, set result->parse_error to an appropriate message
                                347                 :                :  * and return -1.  The caller must check result->parse_error to determine if
                                348                 :                :  * the call was successful.
                                349                 :                :  *
                                350                 :                :  * Valid values are: yes, no, on, off, 1, 0.
                                351                 :                :  *
                                352                 :                :  * Inspired by ParseVariableBool().
                                353                 :                :  */
                                354                 :                : static bool
 1239 tomas.vondra@postgre      355                 :              2 : expect_boolean_value(char *keyword, char *value, pg_compress_specification *result)
                                356                 :                : {
                                357         [ +  - ]:              2 :     if (value == NULL)
                                358                 :              2 :         return true;
                                359                 :                : 
 1239 tomas.vondra@postgre      360         [ #  # ]:UBC           0 :     if (pg_strcasecmp(value, "yes") == 0)
                                361                 :              0 :         return true;
                                362         [ #  # ]:              0 :     if (pg_strcasecmp(value, "on") == 0)
                                363                 :              0 :         return true;
                                364         [ #  # ]:              0 :     if (pg_strcasecmp(value, "1") == 0)
                                365                 :              0 :         return true;
                                366                 :                : 
                                367         [ #  # ]:              0 :     if (pg_strcasecmp(value, "no") == 0)
                                368                 :              0 :         return false;
                                369         [ #  # ]:              0 :     if (pg_strcasecmp(value, "off") == 0)
                                370                 :              0 :         return false;
                                371         [ #  # ]:              0 :     if (pg_strcasecmp(value, "0") == 0)
                                372                 :              0 :         return false;
                                373                 :                : 
                                374                 :              0 :     result->parse_error =
 1196 peter@eisentraut.org      375                 :              0 :         psprintf(_("value for compression option \"%s\" must be a Boolean value"),
                                376                 :                :                  keyword);
 1239 tomas.vondra@postgre      377                 :              0 :     return false;
                                378                 :                : }
                                379                 :                : 
                                380                 :                : /*
                                381                 :                :  * Returns NULL if the compression specification string was syntactically
                                382                 :                :  * valid and semantically sensible.  Otherwise, returns an error message.
                                383                 :                :  *
                                384                 :                :  * Does not test whether this build of PostgreSQL supports the requested
                                385                 :                :  * compression method.
                                386                 :                :  */
                                387                 :                : char *
 1598 michael@paquier.xyz       388                 :CBC         446 : validate_compress_specification(pg_compress_specification *spec)
                                389                 :                : {
 1443                           390                 :            446 :     int         min_level = 1;
                                391                 :            446 :     int         max_level = 1;
                                392                 :            446 :     int         default_level = 0;
                                393                 :                : 
                                394                 :                :     /* If it didn't even parse OK, it's definitely no good. */
 1618 rhaas@postgresql.org      395         [ +  + ]:            446 :     if (spec->parse_error != NULL)
                                396                 :             13 :         return spec->parse_error;
                                397                 :                : 
                                398                 :                :     /*
                                399                 :                :      * Check that the algorithm expects a compression level and it is within
                                400                 :                :      * the legal range for the algorithm.
                                401                 :                :      */
 1443 michael@paquier.xyz       402   [ +  +  -  +  :            433 :     switch (spec->algorithm)
                                                 - ]
                                403                 :                :     {
                                404                 :             76 :         case PG_COMPRESSION_GZIP:
 1618 rhaas@postgresql.org      405                 :             76 :             max_level = 9;
                                406                 :                : #ifdef HAVE_LIBZ
 1443 michael@paquier.xyz       407                 :             76 :             default_level = Z_DEFAULT_COMPRESSION;
                                408                 :                : #endif
                                409                 :             76 :             break;
                                410                 :              9 :         case PG_COMPRESSION_LZ4:
 1618 rhaas@postgresql.org      411                 :              9 :             max_level = 12;
 1443 michael@paquier.xyz       412                 :              9 :             default_level = 0;  /* fast mode */
                                413                 :              9 :             break;
 1443 michael@paquier.xyz       414                 :UBC           0 :         case PG_COMPRESSION_ZSTD:
                                415                 :                : #ifdef USE_ZSTD
                                416                 :                :             max_level = ZSTD_maxCLevel();
                                417                 :                :             min_level = ZSTD_minCLevel();
                                418                 :                :             default_level = ZSTD_CLEVEL_DEFAULT;
                                419                 :                : #endif
                                420                 :              0 :             break;
 1443 michael@paquier.xyz       421                 :CBC         348 :         case PG_COMPRESSION_NONE:
                                422         [ +  + ]:            348 :             if (spec->level != 0)
                                423                 :              3 :                 return psprintf(_("compression algorithm \"%s\" does not accept a compression level"),
                                424                 :                :                                 get_compress_algorithm_name(spec->algorithm));
                                425                 :            345 :             break;
                                426                 :                :     }
                                427                 :                : 
                                428   [ +  +  +  + ]:            430 :     if ((spec->level < min_level || spec->level > max_level) &&
                                429         [ +  + ]:            415 :         spec->level != default_level)
                                430                 :              3 :         return psprintf(_("compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"),
                                431                 :                :                         get_compress_algorithm_name(spec->algorithm),
                                432                 :                :                         min_level, max_level, default_level);
                                433                 :                : 
                                434                 :                :     /*
                                435                 :                :      * Of the compression algorithms that we currently support, only zstd
                                436                 :                :      * allows parallel workers.
                                437                 :                :      */
 1598                           438         [ +  + ]:            427 :     if ((spec->options & PG_COMPRESSION_OPTION_WORKERS) != 0 &&
                                439         [ +  - ]:              2 :         (spec->algorithm != PG_COMPRESSION_ZSTD))
                                440                 :                :     {
 1611 rhaas@postgresql.org      441                 :              2 :         return psprintf(_("compression algorithm \"%s\" does not accept a worker count"),
                                442                 :                :                         get_compress_algorithm_name(spec->algorithm));
                                443                 :                :     }
                                444                 :                : 
                                445                 :                :     /*
                                446                 :                :      * Of the compression algorithms that we currently support, only zstd
                                447                 :                :      * supports long-distance mode.
                                448                 :                :      */
 1239 tomas.vondra@postgre      449         [ +  + ]:            425 :     if ((spec->options & PG_COMPRESSION_OPTION_LONG_DISTANCE) != 0 &&
                                450         [ +  - ]:              2 :         (spec->algorithm != PG_COMPRESSION_ZSTD))
                                451                 :                :     {
                                452                 :              2 :         return psprintf(_("compression algorithm \"%s\" does not support long-distance mode"),
                                453                 :                :                         get_compress_algorithm_name(spec->algorithm));
                                454                 :                :     }
                                455                 :                : 
 1618 rhaas@postgresql.org      456                 :            423 :     return NULL;
                                457                 :                : }
                                458                 :                : 
                                459                 :                : #ifdef FRONTEND
                                460                 :                : 
                                461                 :                : /*
                                462                 :                :  * Basic parsing of a value specified through a command-line option, commonly
                                463                 :                :  * -Z/--compress.
                                464                 :                :  *
                                465                 :                :  * The parsing consists of a METHOD:DETAIL string fed later to
                                466                 :                :  * parse_compress_specification().  This only extracts METHOD and DETAIL.
                                467                 :                :  * If only an integer is found, the method is implied by the value specified.
                                468                 :                :  */
                                469                 :                : void
 1366 michael@paquier.xyz       470                 :             48 : parse_compress_options(const char *option, char **algorithm, char **detail)
                                471                 :                : {
                                472                 :                :     const char *sep;
                                473                 :                :     char       *endp;
                                474                 :                :     long        result;
                                475                 :                : 
                                476                 :                :     /*
                                477                 :                :      * Check whether the compression specification consists of a bare integer.
                                478                 :                :      *
                                479                 :                :      * For backward-compatibility, assume "none" if the integer found is zero
                                480                 :                :      * and "gzip" otherwise.
                                481                 :                :      */
                                482                 :             48 :     result = strtol(option, &endp, 10);
                                483         [ +  + ]:             48 :     if (*endp == '\0')
                                484                 :                :     {
                                485         [ -  + ]:              6 :         if (result == 0)
                                486                 :                :         {
 1366 michael@paquier.xyz       487                 :UBC           0 :             *algorithm = pstrdup("none");
                                488                 :              0 :             *detail = NULL;
                                489                 :                :         }
                                490                 :                :         else
                                491                 :                :         {
 1366 michael@paquier.xyz       492                 :CBC           6 :             *algorithm = pstrdup("gzip");
                                493                 :              6 :             *detail = pstrdup(option);
                                494                 :                :         }
                                495                 :              6 :         return;
                                496                 :                :     }
                                497                 :                : 
                                498                 :                :     /*
                                499                 :                :      * Check whether there is a compression detail following the algorithm
                                500                 :                :      * name.
                                501                 :                :      */
                                502                 :             42 :     sep = strchr(option, ':');
                                503         [ +  + ]:             42 :     if (sep == NULL)
                                504                 :                :     {
                                505                 :             10 :         *algorithm = pstrdup(option);
                                506                 :             10 :         *detail = NULL;
                                507                 :                :     }
                                508                 :                :     else
                                509                 :                :     {
                                510                 :                :         char       *alg;
                                511                 :                : 
                                512                 :             32 :         alg = palloc((sep - option) + 1);
                                513                 :             32 :         memcpy(alg, option, sep - option);
                                514                 :             32 :         alg[sep - option] = '\0';
                                515                 :                : 
                                516                 :             32 :         *algorithm = alg;
                                517                 :             32 :         *detail = pstrdup(sep + 1);
                                518                 :                :     }
                                519                 :                : }
                                520                 :                : #endif                          /* FRONTEND */
        

Generated by: LCOV version 2.0-1