summaryrefslogtreecommitdiff
path: root/src/common/backup_compression.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/backup_compression.c')
-rw-r--r--src/common/backup_compression.c294
1 files changed, 0 insertions, 294 deletions
diff --git a/src/common/backup_compression.c b/src/common/backup_compression.c
deleted file mode 100644
index 867f2f2eb5e..00000000000
--- a/src/common/backup_compression.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * backup_compression.c
- *
- * Shared code for backup compression methods and specifications.
- *
- * A compression specification specifies the parameters that should be used
- * when performing compression with a specific algorithm. The simplest
- * possible compression specification is an integer, which sets the
- * compression level.
- *
- * Otherwise, a compression specification is a comma-separated list of items,
- * each having the form keyword or keyword=value.
- *
- * Currently, the only supported keyword is "level".
- *
- * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * src/common/backup_compression.c
- *-------------------------------------------------------------------------
- */
-
-#ifndef FRONTEND
-#include "postgres.h"
-#else
-#include "postgres_fe.h"
-#endif
-
-#include "common/backup_compression.h"
-
-static int expect_integer_value(char *keyword, char *value,
- bc_specification *result);
-
-/*
- * Look up a compression algorithm by name. Returns true and sets *algorithm
- * if the name is recognized. Otherwise returns false.
- */
-bool
-parse_bc_algorithm(char *name, bc_algorithm *algorithm)
-{
- if (strcmp(name, "none") == 0)
- *algorithm = BACKUP_COMPRESSION_NONE;
- else if (strcmp(name, "gzip") == 0)
- *algorithm = BACKUP_COMPRESSION_GZIP;
- else if (strcmp(name, "lz4") == 0)
- *algorithm = BACKUP_COMPRESSION_LZ4;
- else if (strcmp(name, "zstd") == 0)
- *algorithm = BACKUP_COMPRESSION_ZSTD;
- else
- return false;
- return true;
-}
-
-/*
- * Get the human-readable name corresponding to a particular compression
- * algorithm.
- */
-const char *
-get_bc_algorithm_name(bc_algorithm algorithm)
-{
- switch (algorithm)
- {
- case BACKUP_COMPRESSION_NONE:
- return "none";
- case BACKUP_COMPRESSION_GZIP:
- return "gzip";
- case BACKUP_COMPRESSION_LZ4:
- return "lz4";
- case BACKUP_COMPRESSION_ZSTD:
- return "zstd";
- /* no default, to provoke compiler warnings if values are added */
- }
- Assert(false);
- return "???"; /* placate compiler */
-}
-
-/*
- * Parse a compression specification for a specified algorithm.
- *
- * See the file header comments for a brief description of what a compression
- * specification is expected to look like.
- *
- * On return, all fields of the result object will be initialized.
- * In particular, result->parse_error will be NULL if no errors occurred
- * during parsing, and will otherwise contain an appropriate error message.
- * The caller may free this error message string using pfree, if desired.
- * Note, however, even if there's no parse error, the string might not make
- * sense: e.g. for gzip, level=12 is not sensible, but it does parse OK.
- *
- * Use validate_bc_specification() to find out whether a compression
- * specification is semantically sensible.
- */
-void
-parse_bc_specification(bc_algorithm algorithm, char *specification,
- bc_specification *result)
-{
- int bare_level;
- char *bare_level_endp;
-
- /* Initial setup of result object. */
- result->algorithm = algorithm;
- result->options = 0;
- result->level = -1;
- result->parse_error = NULL;
-
- /* If there is no specification, we're done already. */
- if (specification == NULL)
- return;
-
- /* As a special case, the specification can be a bare integer. */
- bare_level = strtol(specification, &bare_level_endp, 10);
- if (specification != bare_level_endp && *bare_level_endp == '\0')
- {
- result->level = bare_level;
- result->options |= BACKUP_COMPRESSION_OPTION_LEVEL;
- return;
- }
-
- /* Look for comma-separated keyword or keyword=value entries. */
- while (1)
- {
- char *kwstart;
- char *kwend;
- char *vstart;
- char *vend;
- int kwlen;
- int vlen;
- bool has_value;
- char *keyword;
- char *value;
-
- /* Figure start, end, and length of next keyword and any value. */
- kwstart = kwend = specification;
- while (*kwend != '\0' && *kwend != ',' && *kwend != '=')
- ++kwend;
- kwlen = kwend - kwstart;
- if (*kwend != '=')
- {
- vstart = vend = NULL;
- vlen = 0;
- has_value = false;
- }
- else
- {
- vstart = vend = kwend + 1;
- while (*vend != '\0' && *vend != ',')
- ++vend;
- vlen = vend - vstart;
- has_value = true;
- }
-
- /* Reject empty keyword. */
- if (kwlen == 0)
- {
- result->parse_error =
- pstrdup(_("found empty string where a compression option was expected"));
- break;
- }
-
- /* Extract keyword and value as separate C strings. */
- keyword = palloc(kwlen + 1);
- memcpy(keyword, kwstart, kwlen);
- keyword[kwlen] = '\0';
- if (!has_value)
- value = NULL;
- else
- {
- value = palloc(vlen + 1);
- memcpy(value, vstart, vlen);
- value[vlen] = '\0';
- }
-
- /* Handle whatever keyword we found. */
- if (strcmp(keyword, "level") == 0)
- {
- result->level = expect_integer_value(keyword, value, result);
- result->options |= BACKUP_COMPRESSION_OPTION_LEVEL;
- }
- else if (strcmp(keyword, "workers") == 0)
- {
- result->workers = expect_integer_value(keyword, value, result);
- result->options |= BACKUP_COMPRESSION_OPTION_WORKERS;
- }
- else
- result->parse_error =
- psprintf(_("unknown compression option \"%s\""), keyword);
-
- /* Release memory, just to be tidy. */
- pfree(keyword);
- if (value != NULL)
- pfree(value);
-
- /*
- * If we got an error or have reached the end of the string, stop.
- *
- * If there is no value, then the end of the keyword might have been
- * the end of the string. If there is a value, then the end of the
- * keyword cannot have been the end of the string, but the end of the
- * value might have been.
- */
- if (result->parse_error != NULL ||
- (vend == NULL ? *kwend == '\0' : *vend == '\0'))
- break;
-
- /* Advance to next entry and loop around. */
- specification = vend == NULL ? kwend + 1 : vend + 1;
- }
-}
-
-/*
- * Parse 'value' as an integer and return the result.
- *
- * If parsing fails, set result->parse_error to an appropriate message
- * and return -1.
- */
-static int
-expect_integer_value(char *keyword, char *value, bc_specification *result)
-{
- int ivalue;
- char *ivalue_endp;
-
- if (value == NULL)
- {
- result->parse_error =
- psprintf(_("compression option \"%s\" requires a value"),
- keyword);
- return -1;
- }
-
- ivalue = strtol(value, &ivalue_endp, 10);
- if (ivalue_endp == value || *ivalue_endp != '\0')
- {
- result->parse_error =
- psprintf(_("value for compression option \"%s\" must be an integer"),
- keyword);
- return -1;
- }
- return ivalue;
-}
-
-/*
- * Returns NULL if the compression specification string was syntactically
- * valid and semantically sensible. Otherwise, returns an error message.
- *
- * Does not test whether this build of PostgreSQL supports the requested
- * compression method.
- */
-char *
-validate_bc_specification(bc_specification *spec)
-{
- /* If it didn't even parse OK, it's definitely no good. */
- if (spec->parse_error != NULL)
- return spec->parse_error;
-
- /*
- * If a compression level was specified, check that the algorithm expects
- * a compression level and that the level is within the legal range for
- * the algorithm.
- */
- if ((spec->options & BACKUP_COMPRESSION_OPTION_LEVEL) != 0)
- {
- int min_level = 1;
- int max_level;
-
- if (spec->algorithm == BACKUP_COMPRESSION_GZIP)
- max_level = 9;
- else if (spec->algorithm == BACKUP_COMPRESSION_LZ4)
- max_level = 12;
- else if (spec->algorithm == BACKUP_COMPRESSION_ZSTD)
- max_level = 22;
- else
- return psprintf(_("compression algorithm \"%s\" does not accept a compression level"),
- get_bc_algorithm_name(spec->algorithm));
-
- if (spec->level < min_level || spec->level > max_level)
- return psprintf(_("compression algorithm \"%s\" expects a compression level between %d and %d"),
- get_bc_algorithm_name(spec->algorithm),
- min_level, max_level);
- }
-
- /*
- * Of the compression algorithms that we currently support, only zstd
- * allows parallel workers.
- */
- if ((spec->options & BACKUP_COMPRESSION_OPTION_WORKERS) != 0 &&
- (spec->algorithm != BACKUP_COMPRESSION_ZSTD))
- {
- return psprintf(_("compression algorithm \"%s\" does not accept a worker count"),
- get_bc_algorithm_name(spec->algorithm));
- }
-
- return NULL;
-}