Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e5595de

Browse files
committed
Tidy up more loose ends related to configurable TOAST compression.
Change the default_toast_compression GUC to be an enum rather than a string. Earlier, uncommitted versions of the patch supported using CREATE ACCESS METHOD to add new compression methods to a running system, but that idea was dropped before commit. So, we can simplify the GUC handling as well, which has the nice side effect of improving the error messages. While updating the documentation to reflect the new GUC type, also move it back to the right place in the list. I moved this while revising what became commit 24f0e39, but apparently the intended ordering is "alphabetical" rather than "whatever Robert thinks looks nice." Rejigger things to avoid having access/toast_compression.h depend on utils/guc.h, so that we don't end up with every file that includes it also depending on something largely unrelated. Move a few inline functions back into the C source file partly to help reduce dependencies and partly just to avoid clutter. A few very minor cosmetic fixes. Original patch by Justin Pryzby, but very heavily edited by me, and reverse reviewed by him and also reviewed by by Tom Lane. Discussion: http://postgr.es/m/CA+TgmoYp=GT_ztUCeZg2i4hkHAQv8o=-nVJ1-TKWTG1zQOmOpg@mail.gmail.com
1 parent 49ab61f commit e5595de

File tree

6 files changed

+107
-135
lines changed

6 files changed

+107
-135
lines changed

doc/src/sgml/config.sgml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8085,28 +8085,6 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
80858085
</listitem>
80868086
</varlistentry>
80878087

8088-
<varlistentry id="guc-default-toast-compression" xreflabel="default_toast_compression">
8089-
<term><varname>default_toast_compression</varname> (<type>string</type>)
8090-
<indexterm>
8091-
<primary><varname>default_toast_compression</varname> configuration parameter</primary>
8092-
</indexterm>
8093-
</term>
8094-
<listitem>
8095-
<para>
8096-
This variable sets the default
8097-
<link linkend="storage-toast">TOAST</link>
8098-
compression method for columns of newly-created tables. The
8099-
<command>CREATE TABLE</command> statement can override this default
8100-
by specifying the <literal>COMPRESSION</literal> column option.
8101-
8102-
The supported compression methods are <literal>pglz</literal> and
8103-
(if configured at the time <productname>PostgreSQL</productname> was
8104-
built) <literal>lz4</literal>.
8105-
The default is <literal>pglz</literal>.
8106-
</para>
8107-
</listitem>
8108-
</varlistentry>
8109-
81108088
<varlistentry id="guc-default-tablespace" xreflabel="default_tablespace">
81118089
<term><varname>default_tablespace</varname> (<type>string</type>)
81128090
<indexterm>
@@ -8150,6 +8128,28 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
81508128
</listitem>
81518129
</varlistentry>
81528130

8131+
<varlistentry id="guc-default-toast-compression" xreflabel="default_toast_compression">
8132+
<term><varname>default_toast_compression</varname> (<type>enum</type>)
8133+
<indexterm>
8134+
<primary><varname>default_toast_compression</varname> configuration parameter</primary>
8135+
</indexterm>
8136+
</term>
8137+
<listitem>
8138+
<para>
8139+
This variable sets the default
8140+
<link linkend="storage-toast">TOAST</link>
8141+
compression method for columns of newly-created tables. The
8142+
<command>CREATE TABLE</command> statement can override this default
8143+
by specifying the <literal>COMPRESSION</literal> column option.
8144+
8145+
The supported compression methods are <literal>pglz</literal> and
8146+
(if configured at the time <productname>PostgreSQL</productname> was
8147+
built) <literal>lz4</literal>.
8148+
The default is <literal>pglz</literal>.
8149+
</para>
8150+
</listitem>
8151+
</varlistentry>
8152+
81538153
<varlistentry id="guc-temp-tablespaces" xreflabel="temp_tablespaces">
81548154
<term><varname>temp_tablespaces</varname> (<type>string</type>)
81558155
<indexterm>

src/backend/access/common/toast_compression.c

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@
2323
#include "fmgr.h"
2424
#include "utils/builtins.h"
2525

26-
/* Compile-time default */
27-
char *default_toast_compression = DEFAULT_TOAST_COMPRESSION;
26+
/* GUC */
27+
int default_toast_compression = TOAST_PGLZ_COMPRESSION;
28+
29+
#define NO_LZ4_SUPPORT() \
30+
ereport(ERROR, \
31+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
32+
errmsg("unsupported LZ4 compression method"), \
33+
errdetail("This functionality requires the server to be built with lz4 support."), \
34+
errhint("You need to rebuild PostgreSQL using --with-lz4.")))
2835

2936
/*
3037
* Compress a varlena using PGLZ.
@@ -271,46 +278,41 @@ toast_get_compression_id(struct varlena *attr)
271278
}
272279

273280
/*
274-
* Validate a new value for the default_toast_compression GUC.
281+
* CompressionNameToMethod - Get compression method from compression name
282+
*
283+
* Search in the available built-in methods. If the compression not found
284+
* in the built-in methods then return InvalidCompressionMethod.
275285
*/
276-
bool
277-
check_default_toast_compression(char **newval, void **extra, GucSource source)
286+
char
287+
CompressionNameToMethod(const char *compression)
278288
{
279-
if (**newval == '\0')
289+
if (strcmp(compression, "pglz") == 0)
290+
return TOAST_PGLZ_COMPRESSION;
291+
else if (strcmp(compression, "lz4") == 0)
280292
{
281-
GUC_check_errdetail("%s cannot be empty.",
282-
"default_toast_compression");
283-
return false;
293+
#ifndef USE_LZ4
294+
NO_LZ4_SUPPORT();
295+
#endif
296+
return TOAST_LZ4_COMPRESSION;
284297
}
285298

286-
if (strlen(*newval) >= NAMEDATALEN)
287-
{
288-
GUC_check_errdetail("%s is too long (maximum %d characters).",
289-
"default_toast_compression", NAMEDATALEN - 1);
290-
return false;
291-
}
299+
return InvalidCompressionMethod;
300+
}
292301

293-
if (!CompressionMethodIsValid(CompressionNameToMethod(*newval)))
302+
/*
303+
* GetCompressionMethodName - Get compression method name
304+
*/
305+
const char *
306+
GetCompressionMethodName(char method)
307+
{
308+
switch (method)
294309
{
295-
/*
296-
* When source == PGC_S_TEST, don't throw a hard error for a
297-
* nonexistent compression method, only a NOTICE. See comments in
298-
* guc.h.
299-
*/
300-
if (source == PGC_S_TEST)
301-
{
302-
ereport(NOTICE,
303-
(errcode(ERRCODE_UNDEFINED_OBJECT),
304-
errmsg("compression method \"%s\" does not exist",
305-
*newval)));
306-
}
307-
else
308-
{
309-
GUC_check_errdetail("Compression method \"%s\" does not exist.",
310-
*newval);
311-
return false;
312-
}
310+
case TOAST_PGLZ_COMPRESSION:
311+
return "pglz";
312+
case TOAST_LZ4_COMPRESSION:
313+
return "lz4";
314+
default:
315+
elog(ERROR, "invalid compression method %c", method);
316+
return NULL; /* keep compiler quiet */
313317
}
314-
315-
return true;
316318
}

src/backend/utils/misc/guc.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,14 @@ static struct config_enum_entry shared_memory_options[] = {
509509
{NULL, 0, false}
510510
};
511511

512+
static struct config_enum_entry default_toast_compression_options[] = {
513+
{"pglz", TOAST_PGLZ_COMPRESSION, false},
514+
#ifdef USE_LZ4
515+
{"lz4", TOAST_LZ4_COMPRESSION, false},
516+
#endif
517+
{NULL, 0, false}
518+
};
519+
512520
/*
513521
* Options for enum values stored in other modules
514522
*/
@@ -3933,17 +3941,6 @@ static struct config_string ConfigureNamesString[] =
39333941
check_default_table_access_method, NULL, NULL
39343942
},
39353943

3936-
{
3937-
{"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT,
3938-
gettext_noop("Sets the default compression for new columns."),
3939-
NULL,
3940-
GUC_IS_NAME
3941-
},
3942-
&default_toast_compression,
3943-
DEFAULT_TOAST_COMPRESSION,
3944-
check_default_toast_compression, NULL, NULL
3945-
},
3946-
39473944
{
39483945
{"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT,
39493946
gettext_noop("Sets the default tablespace to create tables and indexes in."),
@@ -4585,6 +4582,17 @@ static struct config_enum ConfigureNamesEnum[] =
45854582
NULL, NULL, NULL
45864583
},
45874584

4585+
{
4586+
{"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT,
4587+
gettext_noop("Sets the default compression for new columns."),
4588+
NULL,
4589+
GUC_IS_NAME
4590+
},
4591+
&default_toast_compression,
4592+
TOAST_PGLZ_COMPRESSION,
4593+
default_toast_compression_options, NULL, NULL
4594+
},
4595+
45884596
{
45894597
{"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT,
45904598
gettext_noop("Sets the transaction isolation level of each new transaction."),

src/include/access/toast_compression.h

Lines changed: 22 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,26 @@
1313
#ifndef TOAST_COMPRESSION_H
1414
#define TOAST_COMPRESSION_H
1515

16-
#include "utils/guc.h"
17-
18-
/* GUCs */
19-
extern char *default_toast_compression;
20-
21-
/* default compression method if not specified. */
22-
#define DEFAULT_TOAST_COMPRESSION "pglz"
16+
/*
17+
* GUC support.
18+
*
19+
* default_toast_compression is an integer for purposes of the GUC machinery,
20+
* but the value is one of the char values defined below, as they appear in
21+
* pg_attribute.attcompression, e.g. TOAST_PGLZ_COMPRESSION.
22+
*/
23+
extern int default_toast_compression;
2324

2425
/*
2526
* Built-in compression method-id. The toast compression header will store
2627
* this in the first 2 bits of the raw length. These built-in compression
2728
* method-id are directly mapped to the built-in compression methods.
29+
*
30+
* Don't use these values for anything other than understanding the meaning
31+
* of the raw bits from a varlena; in particular, if the goal is to identify
32+
* a compression method, use the constants TOAST_PGLZ_COMPRESSION, etc.
33+
* below. We might someday support more than 4 compression methods, but
34+
* we can never have more than 4 values in this enum, because there are
35+
* only 2 bits available in the places where this is used.
2836
*/
2937
typedef enum ToastCompressionId
3038
{
@@ -39,60 +47,13 @@ typedef enum ToastCompressionId
3947
*/
4048
#define TOAST_PGLZ_COMPRESSION 'p'
4149
#define TOAST_LZ4_COMPRESSION 'l'
50+
#define InvalidCompressionMethod '\0'
4251

43-
#define InvalidCompressionMethod '\0'
44-
#define CompressionMethodIsValid(cm) ((bool) ((cm) != InvalidCompressionMethod))
45-
46-
#define NO_LZ4_SUPPORT() \
47-
ereport(ERROR, \
48-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \
49-
errmsg("unsupported LZ4 compression method"), \
50-
errdetail("This functionality requires the server to be built with lz4 support."), \
51-
errhint("You need to rebuild PostgreSQL using --with-lz4.")))
52+
#define CompressionMethodIsValid(cm) ((cm) != InvalidCompressionMethod)
5253

5354
#define IsStorageCompressible(storage) ((storage) != TYPSTORAGE_PLAIN && \
5455
(storage) != TYPSTORAGE_EXTERNAL)
5556

56-
/*
57-
* GetCompressionMethodName - Get compression method name
58-
*/
59-
static inline const char *
60-
GetCompressionMethodName(char method)
61-
{
62-
switch (method)
63-
{
64-
case TOAST_PGLZ_COMPRESSION:
65-
return "pglz";
66-
case TOAST_LZ4_COMPRESSION:
67-
return "lz4";
68-
default:
69-
elog(ERROR, "invalid compression method %c", method);
70-
return NULL; /* keep compiler quiet */
71-
}
72-
}
73-
74-
/*
75-
* CompressionNameToMethod - Get compression method from compression name
76-
*
77-
* Search in the available built-in methods. If the compression not found
78-
* in the built-in methods then return InvalidCompressionMethod.
79-
*/
80-
static inline char
81-
CompressionNameToMethod(char *compression)
82-
{
83-
if (strcmp(compression, "pglz") == 0)
84-
return TOAST_PGLZ_COMPRESSION;
85-
else if (strcmp(compression, "lz4") == 0)
86-
{
87-
#ifndef USE_LZ4
88-
NO_LZ4_SUPPORT();
89-
#endif
90-
return TOAST_LZ4_COMPRESSION;
91-
}
92-
93-
return InvalidCompressionMethod;
94-
}
95-
9657
/*
9758
* GetDefaultToastCompression -- get the default toast compression method
9859
*
@@ -101,7 +62,7 @@ CompressionNameToMethod(char *compression)
10162
static inline char
10263
GetDefaultToastCompression(void)
10364
{
104-
return CompressionNameToMethod(default_toast_compression);
65+
return (char) default_toast_compression;
10566
}
10667

10768
/* pglz compression/decompression routines */
@@ -115,8 +76,10 @@ extern struct varlena *lz4_compress_datum(const struct varlena *value);
11576
extern struct varlena *lz4_decompress_datum(const struct varlena *value);
11677
extern struct varlena *lz4_decompress_datum_slice(const struct varlena *value,
11778
int32 slicelength);
79+
80+
/* other stuff */
11881
extern ToastCompressionId toast_get_compression_id(struct varlena *attr);
119-
extern bool check_default_toast_compression(char **newval, void **extra,
120-
GucSource source);
82+
extern char CompressionNameToMethod(const char *compression);
83+
extern const char *GetCompressionMethodName(char method);
12184

12285
#endif /* TOAST_COMPRESSION_H */

src/test/regress/expected/compression.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,10 @@ DETAIL: pglz versus lz4
234234
-- test default_toast_compression GUC
235235
SET default_toast_compression = '';
236236
ERROR: invalid value for parameter "default_toast_compression": ""
237-
DETAIL: default_toast_compression cannot be empty.
237+
HINT: Available values: pglz, lz4.
238238
SET default_toast_compression = 'I do not exist compression';
239239
ERROR: invalid value for parameter "default_toast_compression": "I do not exist compression"
240-
DETAIL: Compression method "I do not exist compression" does not exist.
240+
HINT: Available values: pglz, lz4.
241241
SET default_toast_compression = 'lz4';
242242
DROP TABLE cmdata2;
243243
CREATE TABLE cmdata2 (f1 text);

src/test/regress/expected/compression_1.out

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,13 @@ DETAIL: pglz versus lz4
227227
-- test default_toast_compression GUC
228228
SET default_toast_compression = '';
229229
ERROR: invalid value for parameter "default_toast_compression": ""
230-
DETAIL: default_toast_compression cannot be empty.
230+
HINT: Available values: pglz.
231231
SET default_toast_compression = 'I do not exist compression';
232232
ERROR: invalid value for parameter "default_toast_compression": "I do not exist compression"
233-
DETAIL: Compression method "I do not exist compression" does not exist.
233+
HINT: Available values: pglz.
234234
SET default_toast_compression = 'lz4';
235-
ERROR: unsupported LZ4 compression method
236-
DETAIL: This functionality requires the server to be built with lz4 support.
237-
HINT: You need to rebuild PostgreSQL using --with-lz4.
235+
ERROR: invalid value for parameter "default_toast_compression": "lz4"
236+
HINT: Available values: pglz.
238237
DROP TABLE cmdata2;
239238
CREATE TABLE cmdata2 (f1 text);
240239
\d+ cmdata2

0 commit comments

Comments
 (0)