public inbox for [email protected]
help / color / mirror / Atom feedVariable name typo in launcher.c
30+ messages / 5 participants
[nested] [flat]
* Variable name typo in launcher.c
@ 2017-02-04 23:05 Masahiko Sawada <[email protected]>
0 siblings, 1 reply; 30+ messages in thread
From: Masahiko Sawada @ 2017-02-04 23:05 UTC (permalink / raw)
To: pgsql-hackers
Hi,
I think "laucher" should be "launcher". Attached patch fixes it.
Regards,
--
Masahiko Sawada
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Attachments:
[application/octet-stream] fix_typo_launcher_c.patch (1.3K, ../../CAD21AoC8E8k7ZHO4t1fV8eP9_X+04AABE3-auZEceCjPszQ7qQ@mail.gmail.com/2-fix_typo_launcher_c.patch)
download | inline diff:
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index d222cff..f028d38 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -73,7 +73,7 @@ static void logicalrep_worker_onexit(int code, Datum arg);
static void logicalrep_worker_detach(void);
bool got_SIGTERM = false;
-static bool on_commit_laucher_wakeup = false;
+static bool on_commit_launcher_wakeup = false;
Datum pg_stat_get_subscription(PG_FUNCTION_ARGS);
@@ -170,7 +170,7 @@ WaitForReplicationWorkerAttach(LogicalRepWorker *worker,
/*
* Worker started and attached to our shmem. This check is safe
- * because only laucher ever starts the workers, so nobody can steal
+ * because only launcher ever starts the workers, so nobody can steal
* the worker slot.
*/
if (status == BGWH_STARTED && worker->proc)
@@ -526,7 +526,7 @@ ApplyLauncherShmemInit(void)
void
AtCommit_ApplyLauncher(void)
{
- if (on_commit_laucher_wakeup)
+ if (on_commit_launcher_wakeup)
ApplyLauncherWakeup();
}
@@ -540,8 +540,8 @@ AtCommit_ApplyLauncher(void)
void
ApplyLauncherWakeupAtCommit(void)
{
- if (!on_commit_laucher_wakeup)
- on_commit_laucher_wakeup = true;
+ if (!on_commit_launcher_wakeup)
+ on_commit_launcher_wakeup = true;
}
void
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: Variable name typo in launcher.c
@ 2017-02-06 09:46 Heikki Linnakangas <[email protected]>
parent: Masahiko Sawada <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Heikki Linnakangas @ 2017-02-06 09:46 UTC (permalink / raw)
To: Masahiko Sawada <[email protected]>; pgsql-hackers
On 02/05/2017 01:05 AM, Masahiko Sawada wrote:
> I think "laucher" should be "launcher". Attached patch fixes it.
Fixed, thanks!
- Heikki
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH] fixes to docs and comments
@ 2021-01-09 15:49 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2021-01-09 15:49 UTC (permalink / raw)
---
doc/src/sgml/config.sgml | 10 +++---
doc/src/sgml/libpq.sgml | 23 ++++++++----
doc/src/sgml/protocol.sgml | 54 +++++++++++++----------------
src/backend/libpq/pqcomm.c | 2 +-
src/common/zpq_stream.c | 16 ++++-----
src/include/common/zpq_stream.h | 2 +-
src/interfaces/libpq/fe-connect.c | 2 +-
src/interfaces/libpq/fe-protocol3.c | 26 +++++++-------
8 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 3b132dcf27..8b5a6525ac 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1004,12 +1004,10 @@ include_dir 'conf.d'
</term>
<listitem>
<para>
- When this parameter is <literal>on</literal> (default), the <productname>PostgreSQL</productname>
- server can switch on compression of traffic between server and client if it is requested by client.
- Client sends to the server list of compression algorithms supported by frontend library,
- server chooses one which is supported by backend library and sends it in compression acknowledgement message
- to the client. This option allows to reject compression request even if it is supported by server
- (due to security, CPU consumption or whatever else reasons...).
+ This parameter enables compression of libpq traffic between client and server.
+ The default is <literal>on</literal>.
+ This option allows rejecting compression requests even if it is supported by server
+ (for example, due to security, or CPU consumption).
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2934908520..d4da390ca9 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1244,13 +1244,22 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>compression</literal></term>
<listitem>
<para>
- Request compression of libpq traffic. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and then all libpq messages send both from client to server and
- visa versa will be compressed. If server is not supporting any of the suggested algorithms, then it rejects client request to use compression
- and it is up to the client whether to continue work without compression or report error.
- Supported compression algorithms are chosen at configure time. Right now two libraries are supported: zlib (default) and zstd (if Postgres was
- configured with --with-zstd option). In both cases streaming mode is used.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ Request compression of libpq traffic. The client sends a request with a list of compression algorithms.
+ Compression can be requested by a client by including the "compression" option in its connection string.
+ This can either be a boolean value to enable or disable compression
+ ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto", or an explicit list of comma-separated compression algorithms
+ which can optionally include compression level ("zlib,zstd:5").
+ If compression is enabled but an algorithm is not explicitly specified, the client library sends its full list of
+ supported algorithms and the server chooses a preferred algorithm.
+
+ If the server accepts one of the algorithms, it replies with an acknowledgment and all future libpq messages between client and server
+ will be compressed.
+ If the server rejects the compression request, it is up to the client whether to continue without compression or to report an error.
+ Support for compression algorithms must be enabled when the server is compiled.
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
+ configured with --with-zstd option). In both cases, streaming mode is used.
+ By default, compression is not requested by the client.
+ Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;
</para>
</listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 9f30aad8bd..a69f9bfc26 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -94,10 +94,10 @@
<para>
It is possible to compress protocol data to reduce traffic and speed-up client-server interaction.
- Compression is especially useful for importing/exporting data to/from database using COPY command
- and for replication (both physical and logical). Also compression can reduce server response time
- in case of queries returning large amount of data (for example returning JSON, BLOBs, text,...)
- Right now two libraries are supported: zlib (default) and zstd (if Postgres was
+ Compression is especially useful for importing/exporting data to/from the database using the <literal>COPY</literal> command
+ and for replication (both physical and logical). Compression can also reduce the server's response time
+ for queries returning a large amount of data (for example, JSON, BLOBs, text, ...).
+ Currently, two libraries are supported: zlib (default) and zstd (if Postgres was
configured with --with-zstd option).
</para>
@@ -275,19 +275,14 @@
<term>CompressionAck</term>
<listitem>
<para>
- Server acknowledges using compression for client-server communication protocol.
- Compression can be requested by client by including "compression" option in connection string.
- It can be just boolean values enabling or disabling compression
- ("true"/"false", "on"/"off", "yes"/"no", "1"/"0"), "auto" or explicit list of compression algorithms
- separated by comma with optional specification of compression level: "zlib,zstd:5".
- If compression algorithm is not explicitly specified the most efficient one supported both by
- client and server is chosen. Client sends to the server list of compression algorithms,
- supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and
- all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
+ The server accepts the client's compression request.
+ Compression is requested when a client connection includes the "compression" option, which includes
+ a list of requested compression algorithms.
+ If the server accepts one of these algorithms, it acknowledges use of compression and
+ all subsequent libpq messages between the client and server will be compressed.
+ The server chooses an algorithm from the list specified by client and responds with the index of the chosen algorithm from the client-supplied list.
+ If the server does not accept any of the requested algorithms, then it replies with an index of -1
+ and it is up to the client whether to continue without compression or to report an error.
</para>
</listitem>
</varlistentry>
@@ -3460,12 +3455,14 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Acknowledge use of compression for protocol data. Client sends to the server list of compression algorithms, supported by client library.
- If server supports one of this algorithms, then it acknowledges use of this algorithm and all subsequent libpq messages send both from client to server and
- visa versa will be compressed. Server selects most efficient algorithm among list specified by client and returns to the client
- index of chosen algorithm in this list. If server is not supporting any of the suggested algorithms, then it replies with -1
- and it is up to the client whether to continue work without compression or report error.
- After receiving this message with algorithm index other than -1, both server and client are switched to compression mode
+ Acknowledge use of compression for protocol data. The client sends to the server a list of requested compression algorithms.
+ If the server supports any of these algorithms, it acknowledges use of this algorithm and all subsequent libpq messages between client and server
+ will be compressed.
+ The server selects the preferred algorithm from the list specified by client and responds with the
+ index of the chosen algorithm in this list.
+ If the server does not support any of the requested algorithms, it replies with -1
+ and it is up to the client whether to continue without compression or to report an error.
+ After receiving this message with algorithm index other than -1, both server and client switch to compressed mode
and exchange compressed messages.
</para>
</listitem>
@@ -3486,7 +3483,7 @@ CompressionAck (B)
</term>
<listitem>
<para>
- Index of algorithm in the list of supported algotihms specified by client or -1 if none of them is supported.
+ Index of algorithm in the list of supported algorithms specified by client or -1 if none of them are supported.
</para>
</listitem>
</varlistentry>
@@ -6069,12 +6066,11 @@ StartupMessage (F)
</term>
<listitem>
<para>
- Request compression of libpq traffic. Value is list of compression algorithms supported by client with optional
+ Request compression of libpq traffic. The value is a list of compression algorithms requested by the client with an optional
specification of compression level: <literal>"zlib,zstd:5"</literal>.
- When connecting to an older backend, which does not support compression, or in case when the backend support compression
- but for some reason wants to disable it, the backend will just ignore the _pq_.compression parameter and won’t send
- the compressionAck message to the frontend.
- By default compression is disabled. Please notice that using compression together with SSL may add extra vulnerabilities:
+ If the server does not accept compression, the backend will ignore the _pq_.compression
+ parameter and will not send the CompressionAck message to the frontend.
+ By default, compression is disabled. Please note that using compression together with SSL may expose extra vulnerabilities:
<ulink url="https://en.wikipedia.org/wiki/CRIME">CRIME</ulink;.
</para>
</listitem>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 8be1ce18de..f3293faf01 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -1073,7 +1073,7 @@ pq_recvbuf(bool nowait)
/* Can fill buffer from PqRecvLength and upwards */
for (;;)
{
- /* If streaming compression is enabled then use correspondent compression read function. */
+ /* If streaming compression is enabled then use corresponding compression read function. */
r = PqStream
? zpq_read(PqStream, PqRecvBuffer + PqRecvLength,
PQ_RECV_BUFFER_SIZE - PqRecvLength)
diff --git a/src/common/zpq_stream.c b/src/common/zpq_stream.c
index 459566228a..e044e83e7c 100644
--- a/src/common/zpq_stream.c
+++ b/src/common/zpq_stream.c
@@ -9,15 +9,15 @@
typedef struct
{
/*
- * Returns name of compression algorithm.
+ * Name of compression algorithm.
*/
char const* (*name)(void);
/*
- * Create compression stream with using rx/tx function for fetching/sending compressed data.
+ * Create compression stream with rx/tx function for reading/sending compressed data.
* level: compression level
* tx_func: function for writing compressed data in underlying stream
- * rx_func: function for receiving compressed data from underlying stream
+ * rx_func: function for reading compressed data from underlying stream
* arg: context passed to the function
* rx_data: received data (compressed data already fetched from input stream)
* rx_data_size: size of data fetched from input stream
@@ -27,14 +27,14 @@ typedef struct
/*
* Read up to "size" raw (decompressed) bytes.
* Returns number of decompressed bytes or error code.
- * Error code is either ZPQ_DECOMPRESS_ERROR either error code returned by the rx function.
+ * Error code is either ZPQ_DECOMPRESS_ERROR or error code returned by the rx function.
*/
ssize_t (*read)(ZpqStream *zs, void *buf, size_t size);
/*
* Write up to "size" raw (decompressed) bytes.
* Returns number of written raw bytes or error code returned by tx function.
- * In the last case amount of written raw bytes is stored in *processed.
+ * In the last case number of bytes written is stored in *processed.
*/
ssize_t (*write)(ZpqStream *zs, void const *buf, size_t size, size_t *processed);
@@ -49,12 +49,12 @@ typedef struct
char const* (*error)(ZpqStream *zs);
/*
- * Returns amount of data in internal tx decompression buffer.
+ * Return amount of data in internal tx decompression buffer.
*/
size_t (*buffered_tx)(ZpqStream *zs);
/*
- * Returns amount of data in internal rx compression buffer.
+ * Return amount of data in internal rx compression buffer.
*/
size_t (*buffered_rx)(ZpqStream *zs);
} ZpqAlgorithm;
@@ -265,7 +265,7 @@ zstd_name(void)
#define ZLIB_BUFFER_SIZE 8192 /* We have to flush stream after each protocol command
* and command is mostly limited by record length,
- * which in turn usually less than page size (except TOAST)
+ * which in turn is usually less than page size (except TOAST)
*/
typedef struct ZlibStream
diff --git a/src/include/common/zpq_stream.h b/src/include/common/zpq_stream.h
index 27aef0aab9..991e2c0165 100644
--- a/src/include/common/zpq_stream.h
+++ b/src/include/common/zpq_stream.h
@@ -1,6 +1,6 @@
/*
* zpq_stream.h
- * Streaiming compression for libpq
+ * Streaming compression for libpq
*/
#ifndef ZPQ_STREAM_H
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eac6ef66cc..679f8cde9f 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3269,7 +3269,7 @@ keep_going: /* We will come back to here until there is
{
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
- "server is not supported requested compression algorithms %s\n"),
+ "server does not support requested compression algorithms %s\n"),
conn->compression);
goto error_return;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 095866bba0..5b879569b4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2135,15 +2135,15 @@ pqBuildStartupPacket3(PGconn *conn, int *packetlen,
}
/*
- * Build comma-separated list of compression algorithms suggested by client to the server.
- * It can be either explicitly specified by user in connection string, either
- * include all algorithms supported by clit library.
- * This functions returns true if compression string is successfully parsed and
- * stores comma-separated list of algorithms in *client_compressors.
- * If compression is disabled, then NULL is assigned to *client_compressors.
- * Also it creates array of compressor descriptors, each element of which corresponds
- * the correspondent algorithm name in *client_compressors list. This array is stored in PGconn
- * and is used during handshake when compassion acknowledgment response is received from the server.
+ * Build comma-separated list of compression algorithms requested by client.
+ * It can be either explicitly specified by user in connection string, or
+ * include all algorithms supported by client library.
+ * This function returns true if the compression string is successfully parsed and
+ * stores a comma-separated list of algorithms in *client_compressors.
+ * If compression is disabled, then NULL is assigned to *client_compressors.
+ * Also it creates an array of compressor descriptors, each element of which corresponds to
+ * the corresponding algorithm name in *client_compressors list. This array is stored in PGconn
+ * and is used during handshake when a compression acknowledgment response is received from the server.
*/
static bool
build_compressors_list(PGconn *conn, char** client_compressors, bool build_descriptors)
@@ -2170,7 +2170,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (n_supported_algorithms == 0)
{
- *client_compressors = NULL; /* no compressors are avaialable */
+ *client_compressors = NULL; /* no compressors are available */
conn->compressors = NULL;
return true;
}
@@ -2204,7 +2204,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
}
else
{
- /* List of compresison algorithms separated by commas */
+ /* List of compression algorithms separated by commas */
char *src, *dst;
int n_suggested_algorithms = 0;
char* suggested_algorithms = strdup(value);
@@ -2232,7 +2232,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
if (sscanf(col+1, "%d", &compression_level) != 1 && !build_descriptors)
{
fprintf(stderr,
- libpq_gettext("WARNING: invlaid compression level %s in compression option '%s'\n"),
+ libpq_gettext("WARNING: invalid compression level %s in compression option '%s'\n"),
col+1, value);
return false;
}
@@ -2262,7 +2262,7 @@ build_compressors_list(PGconn *conn, char** client_compressors, bool build_descr
{
if (!build_descriptors)
fprintf(stderr,
- libpq_gettext("WARNING: none of specified algirthms %s is supported by client\n"),
+ libpq_gettext("WARNING: none of the specified algorithms are supported by client: %s\n"),
value);
else
{
--
2.17.0
--yudcn1FV7Hsu/q59--
^ permalink raw reply [nested|flat] 30+ messages in thread
* MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-14 18:20 Jeff Davis <[email protected]>
0 siblings, 1 reply; 30+ messages in thread
From: Jeff Davis @ 2024-02-14 18:20 UTC (permalink / raw)
To: pgsql-hackers; +Cc: Joe Conway <[email protected]>; Robert Haas <[email protected]>; Nathan Bossart <[email protected]>
The MAINTAIN privilege was reverted during the 16 cycle because of the
potential for someone to play tricks with search_path.
For instance, if user foo does:
CREATE FUNCTION mod7(INT) RETURNS INT IMMUTABLE
LANGUAGE plpgsql AS $$ BEGIN RETURN mod($1, 7); END; $$;
CREATE TABLE x(i INT);
CREATE UNIQUE INDEX x_mod7_idx ON x (mod7(i));
GRANT MAINTAIN ON x TO bar;
Then user bar can create their own function named "bar.mod(int, int)",
and "SET search_path = bar, pg_catalog", and then issue a "REINDEX x"
and cause problems.
There are several factors required for that to be a problem:
1. foo hasn't used a "SET search_path" clause on their function
2. bar must have the privileges to create a function somewhere
3. bar must have privileges on table x
There's an argument that we should blame factor #1. Robert stated[1]
that users should use SET search_path clauses on their functions, even
SECURITY INVOKER functions. And I've added a search_path cache which
improves the performance enough to make that more reasonable to do
generally.
There's also an argument that #2 is to blame. Given the realities of
our system, best practice is that users shouldn't have the privileges
to create objects, even in their own schema, unless required. (Joe made
this suggestion in an offline discussion.)
There's also an arugment that #3 is not specific to the MAINTAIN
privilege. Clearly similar risks exist for other privileges, like
TRIGGER. And even the INSERT privilege, in the above example, would
allow bar to violate the unique constraint and corrupt the index[2].
If those arguments are still unconvincing, then the next idea is to fix
the search_path for all maintenance commands[3]. I tried this during
the 16 cycle, but due to timing issues it was also reverted. I can
proceed with this approach again, but I'd like a clear endorsement, in
case there were other reasons to doubt the approach.
Regards,
Jeff Davis
[1]
https://www.postgresql.org/message-id/[email protected]...
[2]
https://www.postgresql.org/message-id/[email protected]
[3]
https://www.postgresql.org/message-id/[email protected]
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-14 19:02 Nathan Bossart <[email protected]>
parent: Jeff Davis <[email protected]>
0 siblings, 2 replies; 30+ messages in thread
From: Nathan Bossart @ 2024-02-14 19:02 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
On Wed, Feb 14, 2024 at 10:20:28AM -0800, Jeff Davis wrote:
> If those arguments are still unconvincing, then the next idea is to fix
> the search_path for all maintenance commands[3]. I tried this during
> the 16 cycle, but due to timing issues it was also reverted. I can
> proceed with this approach again, but I'd like a clear endorsement, in
> case there were other reasons to doubt the approach.
This seemed like the approach folks were most in favor of at the developer
meeting a couple weeks ago [0]. At least, that was my interpretation of
the discussion.
BTW I have been testing reverting commit 151c22d (i.e., un-reverting
MAINTAIN) every month or two, and last I checked, it still applies pretty
cleanly. The only changes I've needed to make are to the catversion and to
a hard-coded version in a test (16 -> 17).
[0] https://wiki.postgresql.org/wiki/FOSDEM/PGDay_2024_Developer_Meeting#The_Path_to_un-reverting_the_MA...
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-15 16:14 Nathan Bossart <[email protected]>
parent: Nathan Bossart <[email protected]>
1 sibling, 0 replies; 30+ messages in thread
From: Nathan Bossart @ 2024-02-15 16:14 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
On Wed, Feb 14, 2024 at 01:02:26PM -0600, Nathan Bossart wrote:
> BTW I have been testing reverting commit 151c22d (i.e., un-reverting
> MAINTAIN) every month or two, and last I checked, it still applies pretty
> cleanly. The only changes I've needed to make are to the catversion and to
> a hard-coded version in a test (16 -> 17).
Posting to get some cfbot coverage.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
Attachments:
[text/x-diff] v1-0001-Revert-Revert-MAINTAIN-privilege-and-pg_maintain-.patch (70.0K, ../../20240215161435.GA858384@nathanxps13/2-v1-0001-Revert-Revert-MAINTAIN-privilege-and-pg_maintain-.patch)
download | inline diff:
From ce4f0c8cc87c2534d46060dc0725783ad6275f21 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
Date: Thu, 15 Feb 2024 10:02:41 -0600
Subject: [PATCH v1 1/1] Revert "Revert MAINTAIN privilege and pg_maintain
predefined role."
XXX: NEEDS CATVERSION BUMP
This reverts commit 151c22deee66a3390ca9a1c3675e29de54ae73fc.
---
doc/src/sgml/ddl.sgml | 35 ++++--
doc/src/sgml/func.sgml | 2 +-
.../sgml/ref/alter_default_privileges.sgml | 4 +-
doc/src/sgml/ref/analyze.sgml | 6 +-
doc/src/sgml/ref/cluster.sgml | 10 +-
doc/src/sgml/ref/grant.sgml | 3 +-
doc/src/sgml/ref/lock.sgml | 4 +-
.../sgml/ref/refresh_materialized_view.sgml | 5 +-
doc/src/sgml/ref/reindex.sgml | 23 ++--
doc/src/sgml/ref/revoke.sgml | 2 +-
doc/src/sgml/ref/vacuum.sgml | 6 +-
doc/src/sgml/user-manag.sgml | 12 ++
src/backend/catalog/aclchk.c | 15 +++
src/backend/commands/analyze.c | 13 +-
src/backend/commands/cluster.c | 43 +++++--
src/backend/commands/indexcmds.c | 34 ++---
src/backend/commands/lockcmds.c | 2 +-
src/backend/commands/matview.c | 3 +-
src/backend/commands/tablecmds.c | 16 +--
src/backend/commands/vacuum.c | 65 +++++-----
src/backend/utils/adt/acl.c | 8 ++
src/bin/pg_dump/dumputils.c | 1 +
src/bin/pg_dump/t/002_pg_dump.pl | 2 +-
src/bin/psql/tab-complete.c | 6 +-
src/include/catalog/pg_authid.dat | 5 +
src/include/commands/tablecmds.h | 5 +-
src/include/commands/vacuum.h | 5 +-
src/include/nodes/parsenodes.h | 3 +-
src/include/utils/acl.h | 5 +-
.../expected/cluster-conflict-partition.out | 8 +-
.../specs/cluster-conflict-partition.spec | 2 +-
.../perl/PostgreSQL/Test/AdjustUpgrade.pm | 11 ++
src/test/regress/expected/cluster.out | 7 ++
src/test/regress/expected/create_index.out | 4 +-
src/test/regress/expected/dependency.out | 22 ++--
src/test/regress/expected/privileges.out | 116 ++++++++++++++----
src/test/regress/expected/rowsecurity.out | 34 ++---
src/test/regress/sql/cluster.sql | 5 +
src/test/regress/sql/dependency.sql | 2 +-
src/test/regress/sql/privileges.sql | 68 ++++++++++
40 files changed, 444 insertions(+), 178 deletions(-)
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index 9d7e2c756b..8616a8e9cc 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -1868,8 +1868,8 @@ ALTER TABLE products RENAME TO items;
<literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>,
<literal>TRUNCATE</literal>, <literal>REFERENCES</literal>, <literal>TRIGGER</literal>,
<literal>CREATE</literal>, <literal>CONNECT</literal>, <literal>TEMPORARY</literal>,
- <literal>EXECUTE</literal>, <literal>USAGE</literal>, <literal>SET</literal>
- and <literal>ALTER SYSTEM</literal>.
+ <literal>EXECUTE</literal>, <literal>USAGE</literal>, <literal>SET</literal>,
+ <literal>ALTER SYSTEM</literal>, and <literal>MAINTAIN</literal>.
The privileges applicable to a particular
object vary depending on the object's type (table, function, etc.).
More detail about the meanings of these privileges appears below.
@@ -2160,7 +2160,19 @@ REVOKE ALL ON accounts FROM PUBLIC;
</para>
</listitem>
</varlistentry>
- </variablelist>
+
+ <varlistentry id="ddl-priv-maintain">
+ <term><literal>MAINTAIN</literal></term>
+ <listitem>
+ <para>
+ Allows <command>VACUUM</command>, <command>ANALYZE</command>,
+ <command>CLUSTER</command>, <command>REFRESH MATERIALIZED VIEW</command>,
+ <command>REINDEX</command>, and <command>LOCK TABLE</command> on a
+ relation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
The privileges required by other commands are listed on the
reference page of the respective command.
@@ -2309,6 +2321,11 @@ REVOKE ALL ON accounts FROM PUBLIC;
<entry><literal>A</literal></entry>
<entry><literal>PARAMETER</literal></entry>
</row>
+ <row>
+ <entry><literal>MAINTAIN</literal></entry>
+ <entry><literal>m</literal></entry>
+ <entry><literal>TABLE</literal></entry>
+ </row>
</tbody>
</tgroup>
</table>
@@ -2399,7 +2416,7 @@ REVOKE ALL ON accounts FROM PUBLIC;
</row>
<row>
<entry><literal>TABLE</literal> (and table-like objects)</entry>
- <entry><literal>arwdDxt</literal></entry>
+ <entry><literal>arwdDxtm</literal></entry>
<entry>none</entry>
<entry><literal>\dp</literal></entry>
</row>
@@ -2465,11 +2482,11 @@ GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;
<programlisting>
=> \dp mytable
Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------+-------+-----------------------+-----------------------+----------
- public | mytable | table | miriam=arwdDxt/miriam+| col1: +|
- | | | =r/miriam +| miriam_rw=rw/miriam |
- | | | admin=arw/miriam | |
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------+-------+------------------------+-----------------------+----------
+ public | mytable | table | miriam=arwdDxtm/miriam+| col1: +|
+ | | | =r/miriam +| miriam_rw=rw/miriam |
+ | | | admin=arw/miriam | |
(1 row)
</programlisting>
</para>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index cf3de80394..f1a64a113e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -24233,7 +24233,7 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
are <literal>SELECT</literal>, <literal>INSERT</literal>,
<literal>UPDATE</literal>, <literal>DELETE</literal>,
<literal>TRUNCATE</literal>, <literal>REFERENCES</literal>,
- and <literal>TRIGGER</literal>.
+ <literal>TRIGGER</literal>, and <literal>MAINTAIN</literal>.
</para></entry>
</row>
diff --git a/doc/src/sgml/ref/alter_default_privileges.sgml b/doc/src/sgml/ref/alter_default_privileges.sgml
index 78744470c8..1de4c5c1b4 100644
--- a/doc/src/sgml/ref/alter_default_privileges.sgml
+++ b/doc/src/sgml/ref/alter_default_privileges.sgml
@@ -28,7 +28,7 @@ ALTER DEFAULT PRIVILEGES
<phrase>where <replaceable class="parameter">abbreviated_grant_or_revoke</replaceable> is one of:</phrase>
-GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON TABLES
TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
@@ -51,7 +51,7 @@ GRANT { USAGE | CREATE | ALL [ PRIVILEGES ] }
TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
REVOKE [ GRANT OPTION FOR ]
- { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON TABLES
FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml
index 6ed8e7241b..0eaf59cb49 100644
--- a/doc/src/sgml/ref/analyze.sgml
+++ b/doc/src/sgml/ref/analyze.sgml
@@ -174,11 +174,9 @@ ANALYZE [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <r
<title>Notes</title>
<para>
- To analyze a table, one must ordinarily be the table's owner or a
- superuser. However, database owners are allowed to
+ To analyze a table, one must ordinarily have the <literal>MAINTAIN</literal>
+ privilege on the table. However, database owners are allowed to
analyze all tables in their databases, except shared catalogs.
- (The restriction for shared catalogs means that a true database-wide
- <command>ANALYZE</command> can only be performed by a superuser.)
<command>ANALYZE</command> will skip over any tables that the calling user
does not have permission to analyze.
</para>
diff --git a/doc/src/sgml/ref/cluster.sgml b/doc/src/sgml/ref/cluster.sgml
index 557a94cea7..b9aa7c8428 100644
--- a/doc/src/sgml/ref/cluster.sgml
+++ b/doc/src/sgml/ref/cluster.sgml
@@ -68,9 +68,8 @@ CLUSTER [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <r
<command>CLUSTER</command> without a
<replaceable class="parameter">table_name</replaceable> reclusters all the
previously-clustered tables in the current database that the calling user
- owns, or all such tables if called by a superuser. This
- form of <command>CLUSTER</command> cannot be executed inside a transaction
- block.
+ has privileges for. This form of <command>CLUSTER</command> cannot be
+ executed inside a transaction block.
</para>
<para>
@@ -131,6 +130,11 @@ CLUSTER [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <r
<refsect1>
<title>Notes</title>
+ <para>
+ To cluster a table, one must have the <literal>MAINTAIN</literal> privilege
+ on the table.
+ </para>
+
<para>
In cases where you are accessing single rows randomly
within a table, the actual order of the data in the
diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml
index 9d27b7fcde..65b1fe7711 100644
--- a/doc/src/sgml/ref/grant.sgml
+++ b/doc/src/sgml/ref/grant.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
-GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
@@ -193,6 +193,7 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
<term><literal>USAGE</literal></term>
<term><literal>SET</literal></term>
<term><literal>ALTER SYSTEM</literal></term>
+ <term><literal>MAINTAIN</literal></term>
<listitem>
<para>
Specific types of privileges, as defined in <xref linkend="ddl-priv"/>.
diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
index 6ce2518de7..070855da18 100644
--- a/doc/src/sgml/ref/lock.sgml
+++ b/doc/src/sgml/ref/lock.sgml
@@ -166,8 +166,8 @@ LOCK [ TABLE ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
<para>
To lock a table, the user must have the right privilege for the specified
- <replaceable class="parameter">lockmode</replaceable>, or be the table's
- owner or a superuser. If the user has
+ <replaceable class="parameter">lockmode</replaceable>.
+ If the user has <literal>MAINTAIN</literal>,
<literal>UPDATE</literal>, <literal>DELETE</literal>, or
<literal>TRUNCATE</literal> privileges on the table, any <replaceable
class="parameter">lockmode</replaceable> is permitted. If the user has
diff --git a/doc/src/sgml/ref/refresh_materialized_view.sgml b/doc/src/sgml/ref/refresh_materialized_view.sgml
index 7a019162c3..4214055692 100644
--- a/doc/src/sgml/ref/refresh_materialized_view.sgml
+++ b/doc/src/sgml/ref/refresh_materialized_view.sgml
@@ -31,8 +31,9 @@ REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] <replaceable class="parameter">name</
<para>
<command>REFRESH MATERIALIZED VIEW</command> completely replaces the
- contents of a materialized view. To execute this command you must be the
- owner of the materialized view. The old contents are discarded. If
+ contents of a materialized view. To execute this command you must have the
+ <literal>MAINTAIN</literal>
+ privilege on the materialized view. The old contents are discarded. If
<literal>WITH DATA</literal> is specified (or defaults) the backing query
is executed to provide the new data, and the materialized view is left in a
scannable state. If <literal>WITH NO DATA</literal> is specified no new
diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
index 21e2e91d89..bef3486843 100644
--- a/doc/src/sgml/ref/reindex.sgml
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -292,16 +292,21 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { DA
</para>
<para>
- Reindexing a single index or table requires being the owner of that
- index or table. Reindexing a schema or database requires being the
- owner of that schema or database. Note specifically that it's thus
+ Reindexing a single index or table requires
+ having the <literal>MAINTAIN</literal> privilege on the
+ table. Note that while <command>REINDEX</command> on a partitioned index or
+ table requires having the <literal>MAINTAIN</literal> privilege on the
+ partitioned table, such commands skip the privilege checks when processing
+ the individual partitions. Reindexing a schema or database requires being the
+ owner of that schema or database or having privileges of the
+ <link linkend="predefined-roles-table"><literal>pg_maintain</literal></link>
+ role. Note specifically that it's thus
possible for non-superusers to rebuild indexes of tables owned by
- other users. However, as a special exception, when
- <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command>
- or <command>REINDEX SYSTEM</command> is issued by a non-superuser,
- indexes on shared catalogs will be skipped unless the user owns the
- catalog (which typically won't be the case). Of course, superusers
- can always reindex anything.
+ other users. However, as a special exception,
+ <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command>,
+ and <command>REINDEX SYSTEM</command> will skip indexes on shared catalogs
+ unless the user has the <literal>MAINTAIN</literal> privilege on the
+ catalog.
</para>
<para>
diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml
index 2db66bbf37..8df492281a 100644
--- a/doc/src/sgml/ref/revoke.sgml
+++ b/doc/src/sgml/ref/revoke.sgml
@@ -22,7 +22,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
REVOKE [ GRANT OPTION FOR ]
- { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER | MAINTAIN }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
| ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml
index a87c2e320e..88c191a262 100644
--- a/doc/src/sgml/ref/vacuum.sgml
+++ b/doc/src/sgml/ref/vacuum.sgml
@@ -434,11 +434,9 @@ VACUUM [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <re
<title>Notes</title>
<para>
- To vacuum a table, one must ordinarily be the table's owner or a
- superuser. However, database owners are allowed to
+ To vacuum a table, one must ordinarily have the <literal>MAINTAIN</literal>
+ privilege on the table. However, database owners are allowed to
vacuum all tables in their databases, except shared catalogs.
- (The restriction for shared catalogs means that a true database-wide
- <command>VACUUM</command> can only be performed by a superuser.)
<command>VACUUM</command> will skip over any tables that the calling user
does not have permission to vacuum.
</para>
diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml
index e026a4e271..07a16247d7 100644
--- a/doc/src/sgml/user-manag.sgml
+++ b/doc/src/sgml/user-manag.sgml
@@ -682,6 +682,18 @@ DROP ROLE doomed_role;
the <link linkend="sql-checkpoint"><command>CHECKPOINT</command></link>
command.</entry>
</row>
+ <row>
+ <entry>pg_maintain</entry>
+ <entry>Allow executing
+ <link linkend="sql-vacuum"><command>VACUUM</command></link>,
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>,
+ <link linkend="sql-cluster"><command>CLUSTER</command></link>,
+ <link linkend="sql-refreshmaterializedview"><command>REFRESH MATERIALIZED VIEW</command></link>,
+ <link linkend="sql-reindex"><command>REINDEX</command></link>,
+ and <link linkend="sql-lock"><command>LOCK TABLE</command></link> on all
+ relations, as if having <literal>MAINTAIN</literal> rights on those
+ objects, even without having it explicitly.</entry>
+ </row>
<row>
<entry>pg_use_reserved_connections</entry>
<entry>Allow use of connection slots reserved via
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 1e44a71f61..8820a88912 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -2644,6 +2644,8 @@ string_to_privilege(const char *privname)
return ACL_SET;
if (strcmp(privname, "alter system") == 0)
return ACL_ALTER_SYSTEM;
+ if (strcmp(privname, "maintain") == 0)
+ return ACL_MAINTAIN;
if (strcmp(privname, "rule") == 0)
return 0; /* ignore old RULE privileges */
ereport(ERROR,
@@ -2685,6 +2687,8 @@ privilege_to_string(AclMode privilege)
return "SET";
case ACL_ALTER_SYSTEM:
return "ALTER SYSTEM";
+ case ACL_MAINTAIN:
+ return "MAINTAIN";
default:
elog(ERROR, "unrecognized privilege: %d", (int) privilege);
}
@@ -3443,6 +3447,17 @@ pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask,
has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA))
result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
+ /*
+ * Check if ACL_MAINTAIN is being checked and, if so, and not already set
+ * as part of the result, then check if the user is a member of the
+ * pg_maintain role, which allows VACUUM, ANALYZE, CLUSTER, REFRESH
+ * MATERIALIZED VIEW, and REINDEX on all relations.
+ */
+ if (mask & ACL_MAINTAIN &&
+ !(result & ACL_MAINTAIN) &&
+ has_privs_of_role(roleid, ROLE_PG_MAINTAIN))
+ result |= ACL_MAINTAIN;
+
return result;
}
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index a03495d6c9..acc774e41a 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -159,16 +159,15 @@ analyze_rel(Oid relid, RangeVar *relation,
return;
/*
- * Check if relation needs to be skipped based on ownership. This check
+ * Check if relation needs to be skipped based on privileges. This check
* happens also when building the relation list to analyze for a manual
* operation, and needs to be done additionally here as ANALYZE could
- * happen across multiple transactions where relation ownership could have
- * changed in-between. Make sure to generate only logs for ANALYZE in
- * this case.
+ * happen across multiple transactions where privileges could have changed
+ * in-between. Make sure to generate only logs for ANALYZE in this case.
*/
- if (!vacuum_is_relation_owner(RelationGetRelid(onerel),
- onerel->rd_rel,
- params->options & VACOPT_ANALYZE))
+ if (!vacuum_is_permitted_for_relation(RelationGetRelid(onerel),
+ onerel->rd_rel,
+ params->options & ~VACOPT_VACUUM))
{
relation_close(onerel, ShareUpdateExclusiveLock);
return;
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index e2c48ec560..44b4dbdb6b 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -80,6 +80,7 @@ static void copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex,
static List *get_tables_to_cluster(MemoryContext cluster_context);
static List *get_tables_to_cluster_partitioned(MemoryContext cluster_context,
Oid indexOid);
+static bool cluster_is_permitted_for_relation(Oid relid, Oid userid);
/*---------------------------------------------------------------------------
@@ -147,7 +148,8 @@ cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
tableOid = RangeVarGetRelidExtended(stmt->relation,
AccessExclusiveLock,
0,
- RangeVarCallbackOwnsTable, NULL);
+ RangeVarCallbackMaintainsTable,
+ NULL);
rel = table_open(tableOid, NoLock);
/*
@@ -364,8 +366,8 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
*/
if (recheck)
{
- /* Check that the user still owns the relation */
- if (!object_ownercheck(RelationRelationId, tableOid, save_userid))
+ /* Check that the user still has privileges for the relation */
+ if (!cluster_is_permitted_for_relation(tableOid, save_userid))
{
relation_close(OldHeap, AccessExclusiveLock);
goto out;
@@ -1621,7 +1623,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
/*
- * Get a list of tables that the current user owns and
+ * Get a list of tables that the current user has privileges on and
* have indisclustered set. Return the list in a List * of RelToCluster
* (stored in the specified memory context), each one giving the tableOid
* and the indexOid on which the table is already clustered.
@@ -1638,8 +1640,8 @@ get_tables_to_cluster(MemoryContext cluster_context)
List *rtcs = NIL;
/*
- * Get all indexes that have indisclustered set and are owned by
- * appropriate user.
+ * Get all indexes that have indisclustered set and that the current user
+ * has the appropriate privileges for.
*/
indRelation = table_open(IndexRelationId, AccessShareLock);
ScanKeyInit(&entry,
@@ -1653,7 +1655,7 @@ get_tables_to_cluster(MemoryContext cluster_context)
index = (Form_pg_index) GETSTRUCT(indexTuple);
- if (!object_ownercheck(RelationRelationId, index->indrelid, GetUserId()))
+ if (!cluster_is_permitted_for_relation(index->indrelid, GetUserId()))
continue;
/* Use a permanent memory context for the result list */
@@ -1701,10 +1703,13 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid)
if (get_rel_relkind(indexrelid) != RELKIND_INDEX)
continue;
- /* Silently skip partitions which the user has no access to. */
- if (!object_ownercheck(RelationRelationId, relid, GetUserId()) &&
- (!object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) ||
- IsSharedRelation(relid)))
+ /*
+ * It's possible that the user does not have privileges to CLUSTER the
+ * leaf partition despite having such privileges on the partitioned
+ * table. We skip any partitions which the user is not permitted to
+ * CLUSTER.
+ */
+ if (!cluster_is_permitted_for_relation(relid, GetUserId()))
continue;
/* Use a permanent memory context for the result list */
@@ -1720,3 +1725,19 @@ get_tables_to_cluster_partitioned(MemoryContext cluster_context, Oid indexOid)
return rtcs;
}
+
+/*
+ * Return whether userid has privileges to CLUSTER relid. If not, this
+ * function emits a WARNING.
+ */
+static bool
+cluster_is_permitted_for_relation(Oid relid, Oid userid)
+{
+ if (pg_class_aclcheck(relid, userid, ACL_MAINTAIN) == ACLCHECK_OK)
+ return true;
+
+ ereport(WARNING,
+ (errmsg("permission denied to cluster \"%s\", skipping it",
+ get_rel_name(relid))));
+ return false;
+}
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 7a87626f5f..d1052881d9 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -27,6 +27,7 @@
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/pg_am.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_database.h"
#include "catalog/pg_inherits.h"
@@ -2944,6 +2945,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
char relkind;
struct ReindexIndexCallbackState *state = arg;
LOCKMODE table_lockmode;
+ Oid table_oid;
/*
* Lock level here should match table lock in reindex_index() for
@@ -2983,14 +2985,19 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
errmsg("\"%s\" is not an index", relation->relname)));
/* Check permissions */
- if (!object_ownercheck(RelationRelationId, relId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_INDEX, relation->relname);
+ table_oid = IndexGetRelation(relId, true);
+ if (OidIsValid(table_oid))
+ {
+ AclResult aclresult;
+
+ aclresult = pg_class_aclcheck(table_oid, GetUserId(), ACL_MAINTAIN);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_INDEX, relation->relname);
+ }
/* Lock heap before index to avoid deadlock. */
if (relId != oldRelId)
{
- Oid table_oid = IndexGetRelation(relId, true);
-
/*
* If the OID isn't valid, it means the index was concurrently
* dropped, which is not a problem for us; just return normally.
@@ -3026,7 +3033,7 @@ ReindexTable(const ReindexStmt *stmt, const ReindexParams *params, bool isTopLev
(params->options & REINDEXOPT_CONCURRENTLY) != 0 ?
ShareUpdateExclusiveLock : ShareLock,
0,
- RangeVarCallbackOwnsTable, NULL);
+ RangeVarCallbackMaintainsTable, NULL);
if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE)
ReindexPartitions(stmt, heapOid, params, isTopLevel);
@@ -3110,7 +3117,8 @@ ReindexMultipleTables(const ReindexStmt *stmt, const ReindexParams *params)
{
objectOid = get_namespace_oid(objectName, false);
- if (!object_ownercheck(NamespaceRelationId, objectOid, GetUserId()))
+ if (!object_ownercheck(NamespaceRelationId, objectOid, GetUserId()) &&
+ !has_privs_of_role(GetUserId(), ROLE_PG_MAINTAIN))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA,
objectName);
}
@@ -3122,7 +3130,8 @@ ReindexMultipleTables(const ReindexStmt *stmt, const ReindexParams *params)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("can only reindex the currently open database")));
- if (!object_ownercheck(DatabaseRelationId, objectOid, GetUserId()))
+ if (!object_ownercheck(DatabaseRelationId, objectOid, GetUserId()) &&
+ !has_privs_of_role(GetUserId(), ROLE_PG_MAINTAIN))
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE,
get_database_name(objectOid));
}
@@ -3194,15 +3203,12 @@ ReindexMultipleTables(const ReindexStmt *stmt, const ReindexParams *params)
continue;
/*
- * The table can be reindexed if the user is superuser, the table
- * owner, or the database/schema owner (but in the latter case, only
- * if it's not a shared relation). object_ownercheck includes the
- * superuser case, and depending on objectKind we already know that
- * the user has permission to run REINDEX on this database or schema
- * per the permission checks at the beginning of this routine.
+ * We already checked privileges on the database or schema, but we
+ * further restrict reindexing shared catalogs to roles with the
+ * MAINTAIN privilege on the relation.
*/
if (classtuple->relisshared &&
- !object_ownercheck(RelationRelationId, relid, GetUserId()))
+ pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) != ACLCHECK_OK)
continue;
/*
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index 29e9953bf4..3170b3e3a1 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -284,7 +284,7 @@ LockTableAclCheck(Oid reloid, LOCKMODE lockmode, Oid userid)
AclMode aclmask;
/* any of these privileges permit any lock mode */
- aclmask = ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
+ aclmask = ACL_MAINTAIN | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
/* SELECT privileges also permit ACCESS SHARE and below */
if (lockmode <= AccessShareLock)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 59920ced83..848931b483 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -165,7 +165,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
*/
matviewOid = RangeVarGetRelidExtended(stmt->relation,
lockmode, 0,
- RangeVarCallbackOwnsTable, NULL);
+ RangeVarCallbackMaintainsTable,
+ NULL);
matviewRel = table_open(matviewOid, NoLock);
relowner = matviewRel->rd_rel->relowner;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 86ea3a228b..0b76ddba8f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -18087,15 +18087,16 @@ AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid,
* This is intended as a callback for RangeVarGetRelidExtended(). It allows
* the relation to be locked only if (1) it's a plain or partitioned table,
* materialized view, or TOAST table and (2) the current user is the owner (or
- * the superuser). This meets the permission-checking needs of CLUSTER,
- * REINDEX TABLE, and REFRESH MATERIALIZED VIEW; we expose it here so that it
- * can be used by all.
+ * the superuser) or has been granted MAINTAIN. This meets the
+ * permission-checking needs of CLUSTER, REINDEX TABLE, and REFRESH
+ * MATERIALIZED VIEW; we expose it here so that it can be used by all.
*/
void
-RangeVarCallbackOwnsTable(const RangeVar *relation,
- Oid relId, Oid oldRelId, void *arg)
+RangeVarCallbackMaintainsTable(const RangeVar *relation,
+ Oid relId, Oid oldRelId, void *arg)
{
char relkind;
+ AclResult aclresult;
/* Nothing to do if the relation was not found. */
if (!OidIsValid(relId))
@@ -18116,8 +18117,9 @@ RangeVarCallbackOwnsTable(const RangeVar *relation,
errmsg("\"%s\" is not a table or materialized view", relation->relname)));
/* Check permissions */
- if (!object_ownercheck(RelationRelationId, relId, GetUserId()))
- aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)), relation->relname);
+ aclresult = pg_class_aclcheck(relId, GetUserId(), ACL_MAINTAIN);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_TABLE, relation->relname);
}
/*
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 64da848627..13c012af50 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -697,32 +697,35 @@ vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy,
}
/*
- * Check if a given relation can be safely vacuumed or analyzed. If the
- * user is not the relation owner, issue a WARNING log message and return
- * false to let the caller decide what to do with this relation. This
- * routine is used to decide if a relation can be processed for VACUUM or
- * ANALYZE.
+ * Check if the current user has privileges to vacuum or analyze the relation.
+ * If not, issue a WARNING log message and return false to let the caller
+ * decide what to do with this relation. This routine is used to decide if a
+ * relation can be processed for VACUUM or ANALYZE.
*/
bool
-vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options)
+vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple,
+ bits32 options)
{
char *relname;
Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0);
/*
- * Check permissions.
- *
- * We allow the user to vacuum or analyze a table if he is superuser, the
- * table owner, or the database owner (but in the latter case, only if
- * it's not a shared relation). object_ownercheck includes the superuser
- * case.
- *
- * Note we choose to treat permissions failure as a WARNING and keep
- * trying to vacuum or analyze the rest of the DB --- is this appropriate?
+ * Privilege checks are bypassed in some cases (e.g., when recursing to a
+ * relation's TOAST table).
*/
- if (object_ownercheck(RelationRelationId, relid, GetUserId()) ||
- (object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared))
+ if (options & VACOPT_SKIP_PRIVS)
+ return true;
+
+ /*----------
+ * A role has privileges to vacuum or analyze the relation if any of the
+ * following are true:
+ * - the role owns the current database and the relation is not shared
+ * - the role has the MAINTAIN privilege on the relation
+ *----------
+ */
+ if ((object_ownercheck(DatabaseRelationId, MyDatabaseId, GetUserId()) && !reltuple->relisshared) ||
+ pg_class_aclcheck(relid, GetUserId(), ACL_MAINTAIN) == ACLCHECK_OK)
return true;
relname = NameStr(reltuple->relname);
@@ -938,10 +941,10 @@ expand_vacuum_rel(VacuumRelation *vrel, MemoryContext vac_context,
classForm = (Form_pg_class) GETSTRUCT(tuple);
/*
- * Make a returnable VacuumRelation for this rel if user is a proper
- * owner.
+ * Make a returnable VacuumRelation for this rel if the user has the
+ * required privileges.
*/
- if (vacuum_is_relation_owner(relid, classForm, options))
+ if (vacuum_is_permitted_for_relation(relid, classForm, options))
{
oldcontext = MemoryContextSwitchTo(vac_context);
vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation,
@@ -1038,7 +1041,7 @@ get_all_vacuum_rels(MemoryContext vac_context, int options)
continue;
/* check permissions of relation */
- if (!vacuum_is_relation_owner(relid, classForm, options))
+ if (!vacuum_is_permitted_for_relation(relid, classForm, options))
continue;
/*
@@ -2030,16 +2033,15 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
}
/*
- * Check if relation needs to be skipped based on ownership. This check
+ * Check if relation needs to be skipped based on privileges. This check
* happens also when building the relation list to vacuum for a manual
* operation, and needs to be done additionally here as VACUUM could
- * happen across multiple transactions where relation ownership could have
- * changed in-between. Make sure to only generate logs for VACUUM in this
- * case.
+ * happen across multiple transactions where privileges could have changed
+ * in-between. Make sure to only generate logs for VACUUM in this case.
*/
- if (!vacuum_is_relation_owner(RelationGetRelid(rel),
- rel->rd_rel,
- params->options & VACOPT_VACUUM))
+ if (!vacuum_is_permitted_for_relation(RelationGetRelid(rel),
+ rel->rd_rel,
+ params->options & ~VACOPT_ANALYZE))
{
relation_close(rel, lmode);
PopActiveSnapshot();
@@ -2225,9 +2227,14 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
{
VacuumParams toast_vacuum_params;
- /* force VACOPT_PROCESS_MAIN so vacuum_rel() processes it */
+ /*
+ * Force VACOPT_PROCESS_MAIN so vacuum_rel() processes it. Likewise,
+ * set VACOPT_SKIP_PRIVS since privileges on the main relation are
+ * sufficient to process it.
+ */
memcpy(&toast_vacuum_params, params, sizeof(VacuumParams));
toast_vacuum_params.options |= VACOPT_PROCESS_MAIN;
+ toast_vacuum_params.options |= VACOPT_SKIP_PRIVS;
vacuum_rel(toast_relid, NULL, &toast_vacuum_params, bstrategy);
}
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 85555d1c5a..2c9a8e8707 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -332,6 +332,9 @@ aclparse(const char *s, AclItem *aip, Node *escontext)
case ACL_ALTER_SYSTEM_CHR:
read = ACL_ALTER_SYSTEM;
break;
+ case ACL_MAINTAIN_CHR:
+ read = ACL_MAINTAIN;
+ break;
case 'R': /* ignore old RULE privileges */
read = 0;
break;
@@ -1623,6 +1626,7 @@ makeaclitem(PG_FUNCTION_ARGS)
{"CONNECT", ACL_CONNECT},
{"SET", ACL_SET},
{"ALTER SYSTEM", ACL_ALTER_SYSTEM},
+ {"MAINTAIN", ACL_MAINTAIN},
{"RULE", 0}, /* ignore old RULE privileges */
{NULL, 0}
};
@@ -1731,6 +1735,8 @@ convert_aclright_to_string(int aclright)
return "SET";
case ACL_ALTER_SYSTEM:
return "ALTER SYSTEM";
+ case ACL_MAINTAIN:
+ return "MAINTAIN";
default:
elog(ERROR, "unrecognized aclright: %d", aclright);
return NULL;
@@ -2043,6 +2049,8 @@ convert_table_priv_string(text *priv_type_text)
{"REFERENCES WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_REFERENCES)},
{"TRIGGER", ACL_TRIGGER},
{"TRIGGER WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_TRIGGER)},
+ {"MAINTAIN", ACL_MAINTAIN},
+ {"MAINTAIN WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_MAINTAIN)},
{"RULE", 0}, /* ignore old RULE privileges */
{"RULE WITH GRANT OPTION", 0},
{NULL, 0}
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 78193c3c2b..5649859aa1 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -463,6 +463,7 @@ do { \
CONVERT_PRIV('d', "DELETE");
CONVERT_PRIV('t', "TRIGGER");
CONVERT_PRIV('D', "TRUNCATE");
+ CONVERT_PRIV('m', "MAINTAIN");
}
}
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index 00b5092713..c8b489d94e 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -794,7 +794,7 @@ my %tests = (
\QREVOKE ALL ON TABLES FROM regress_dump_test_role;\E\n
\QALTER DEFAULT PRIVILEGES \E
\QFOR ROLE regress_dump_test_role \E
- \QGRANT INSERT,REFERENCES,DELETE,TRIGGER,TRUNCATE,UPDATE ON TABLES TO regress_dump_test_role;\E
+ \QGRANT INSERT,REFERENCES,DELETE,TRIGGER,TRUNCATE,MAINTAIN,UPDATE ON TABLES TO regress_dump_test_role;\E
/xm,
like => { %full_runs, section_post_data => 1, },
unlike => { no_privs => 1, },
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 151a5211ee..834357ced3 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1151,7 +1151,7 @@ Keywords_for_list_of_owner_roles, "PUBLIC"
#define Privilege_options_of_grant_and_revoke \
"SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", \
"CREATE", "CONNECT", "TEMPORARY", "EXECUTE", "USAGE", "SET", "ALTER SYSTEM", \
-"ALL"
+"MAINTAIN", "ALL"
/* ALTER PROCEDURE options */
#define Alter_procedure_options \
@@ -3942,7 +3942,7 @@ psql_completion(const char *text, int start, int end)
if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES"))
COMPLETE_WITH("SELECT", "INSERT", "UPDATE",
"DELETE", "TRUNCATE", "REFERENCES", "TRIGGER",
- "CREATE", "EXECUTE", "USAGE", "ALL");
+ "CREATE", "EXECUTE", "USAGE", "MAINTAIN", "ALL");
else if (TailMatches("GRANT"))
COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_roles,
Privilege_options_of_grant_and_revoke);
@@ -3994,7 +3994,7 @@ psql_completion(const char *text, int start, int end)
else if (TailMatches("GRANT|REVOKE", MatchAny) ||
TailMatches("REVOKE", "GRANT", "OPTION", "FOR", MatchAny))
{
- if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL"))
+ if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|MAINTAIN|ALL"))
COMPLETE_WITH("ON");
else if (TailMatches("GRANT", MatchAny))
COMPLETE_WITH("TO");
diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat
index 82a2ec2862..55cabdda6f 100644
--- a/src/include/catalog/pg_authid.dat
+++ b/src/include/catalog/pg_authid.dat
@@ -84,6 +84,11 @@
rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
rolpassword => '_null_', rolvaliduntil => '_null_' },
+{ oid => '9256', oid_symbol => 'ROLE_PG_MAINTAIN',
+ rolname => 'pg_maintain', rolsuper => 'f', rolinherit => 't',
+ rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
+ rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1',
+ rolpassword => '_null_', rolvaliduntil => '_null_' },
{ oid => '4550', oid_symbol => 'ROLE_PG_USE_RESERVED_CONNECTIONS',
rolname => 'pg_use_reserved_connections', rolsuper => 'f', rolinherit => 't',
rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f',
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index 60d9b8f5b5..85cbad3d0c 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -98,8 +98,9 @@ extern void AtEOSubXact_on_commit_actions(bool isCommit,
SubTransactionId mySubid,
SubTransactionId parentSubid);
-extern void RangeVarCallbackOwnsTable(const RangeVar *relation,
- Oid relId, Oid oldRelId, void *arg);
+extern void RangeVarCallbackMaintainsTable(const RangeVar *relation,
+ Oid relId, Oid oldRelId,
+ void *arg);
extern void RangeVarCallbackOwnsRelation(const RangeVar *relation,
Oid relId, Oid oldRelId, void *arg);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 7f623b37fd..f935f39133 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -187,6 +187,7 @@ typedef struct VacAttrStats
#define VACOPT_DISABLE_PAGE_SKIPPING 0x100 /* don't skip any pages */
#define VACOPT_SKIP_DATABASE_STATS 0x200 /* skip vac_update_datfrozenxid() */
#define VACOPT_ONLY_DATABASE_STATS 0x400 /* only vac_update_datfrozenxid() */
+#define VACOPT_SKIP_PRIVS 0x800 /* skip privilege checks */
/*
* Values used by index_cleanup and truncate params.
@@ -343,8 +344,8 @@ extern bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params,
extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs);
extern void vac_update_datfrozenxid(void);
extern void vacuum_delay_point(void);
-extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple,
- bits32 options);
+extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple,
+ bits32 options);
extern Relation vacuum_open_relation(Oid relid, RangeVar *relation,
bits32 options, bool verbose,
LOCKMODE lmode);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 476d55dd24..bbe13f0379 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -87,7 +87,8 @@ typedef uint64 AclMode; /* a bitmask of privilege bits */
#define ACL_CONNECT (1<<11) /* for databases */
#define ACL_SET (1<<12) /* for configuration parameters */
#define ACL_ALTER_SYSTEM (1<<13) /* for configuration parameters */
-#define N_ACL_RIGHTS 14 /* 1 plus the last 1<<x */
+#define ACL_MAINTAIN (1<<14) /* for relations */
+#define N_ACL_RIGHTS 15 /* 1 plus the last 1<<x */
#define ACL_NO_RIGHTS 0
/* Currently, SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges */
#define ACL_SELECT_FOR_UPDATE ACL_UPDATE
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index a803eb1291..3a0baf3039 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -148,15 +148,16 @@ typedef struct ArrayType Acl;
#define ACL_CONNECT_CHR 'c'
#define ACL_SET_CHR 's'
#define ACL_ALTER_SYSTEM_CHR 'A'
+#define ACL_MAINTAIN_CHR 'm'
/* string holding all privilege code chars, in order by bitmask position */
-#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTcsA"
+#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTcsAm"
/*
* Bitmasks defining "all rights" for each supported object type
*/
#define ACL_ALL_RIGHTS_COLUMN (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES)
-#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER)
+#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER|ACL_MAINTAIN)
#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT)
#define ACL_ALL_RIGHTS_FDW (ACL_USAGE)
diff --git a/src/test/isolation/expected/cluster-conflict-partition.out b/src/test/isolation/expected/cluster-conflict-partition.out
index 7acb675c97..7be9e56ef1 100644
--- a/src/test/isolation/expected/cluster-conflict-partition.out
+++ b/src/test/isolation/expected/cluster-conflict-partition.out
@@ -3,7 +3,7 @@ Parsed test spec with 2 sessions
starting permutation: s1_begin s1_lock_parent s2_auth s2_cluster s1_commit s2_reset
step s1_begin: BEGIN;
step s1_lock_parent: LOCK cluster_part_tab IN SHARE UPDATE EXCLUSIVE MODE;
-step s2_auth: SET ROLE regress_cluster_part;
+step s2_auth: SET ROLE regress_cluster_part; SET client_min_messages = ERROR;
step s2_cluster: CLUSTER cluster_part_tab USING cluster_part_ind; <waiting ...>
step s1_commit: COMMIT;
step s2_cluster: <... completed>
@@ -11,7 +11,7 @@ step s2_reset: RESET ROLE;
starting permutation: s1_begin s2_auth s1_lock_parent s2_cluster s1_commit s2_reset
step s1_begin: BEGIN;
-step s2_auth: SET ROLE regress_cluster_part;
+step s2_auth: SET ROLE regress_cluster_part; SET client_min_messages = ERROR;
step s1_lock_parent: LOCK cluster_part_tab IN SHARE UPDATE EXCLUSIVE MODE;
step s2_cluster: CLUSTER cluster_part_tab USING cluster_part_ind; <waiting ...>
step s1_commit: COMMIT;
@@ -21,14 +21,14 @@ step s2_reset: RESET ROLE;
starting permutation: s1_begin s1_lock_child s2_auth s2_cluster s1_commit s2_reset
step s1_begin: BEGIN;
step s1_lock_child: LOCK cluster_part_tab1 IN SHARE UPDATE EXCLUSIVE MODE;
-step s2_auth: SET ROLE regress_cluster_part;
+step s2_auth: SET ROLE regress_cluster_part; SET client_min_messages = ERROR;
step s2_cluster: CLUSTER cluster_part_tab USING cluster_part_ind;
step s1_commit: COMMIT;
step s2_reset: RESET ROLE;
starting permutation: s1_begin s2_auth s1_lock_child s2_cluster s1_commit s2_reset
step s1_begin: BEGIN;
-step s2_auth: SET ROLE regress_cluster_part;
+step s2_auth: SET ROLE regress_cluster_part; SET client_min_messages = ERROR;
step s1_lock_child: LOCK cluster_part_tab1 IN SHARE UPDATE EXCLUSIVE MODE;
step s2_cluster: CLUSTER cluster_part_tab USING cluster_part_ind;
step s1_commit: COMMIT;
diff --git a/src/test/isolation/specs/cluster-conflict-partition.spec b/src/test/isolation/specs/cluster-conflict-partition.spec
index 5091f684a9..4d38a7f49a 100644
--- a/src/test/isolation/specs/cluster-conflict-partition.spec
+++ b/src/test/isolation/specs/cluster-conflict-partition.spec
@@ -23,7 +23,7 @@ step s1_lock_child { LOCK cluster_part_tab1 IN SHARE UPDATE EXCLUSIVE MODE;
step s1_commit { COMMIT; }
session s2
-step s2_auth { SET ROLE regress_cluster_part; }
+step s2_auth { SET ROLE regress_cluster_part; SET client_min_messages = ERROR; }
step s2_cluster { CLUSTER cluster_part_tab USING cluster_part_ind; }
step s2_reset { RESET ROLE; }
diff --git a/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm b/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm
index a6222ae14c..6f853e619c 100644
--- a/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm
+++ b/src/test/perl/PostgreSQL/Test/AdjustUpgrade.pm
@@ -287,6 +287,17 @@ sub adjust_old_dumpfile
$dump = _mash_view_qualifiers($dump);
}
+ if ($old_version >= 14 && $old_version < 17)
+ {
+ # Fix up some privilege-set discrepancies.
+ $dump =~
+ s {^REVOKE SELECT,INSERT,REFERENCES,DELETE,TRIGGER,TRUNCATE,UPDATE ON TABLE}
+ {REVOKE ALL ON TABLE}mg;
+ $dump =~
+ s {^(GRANT SELECT,INSERT,REFERENCES,TRIGGER,TRUNCATE),UPDATE ON TABLE}
+ {$1,MAINTAIN,UPDATE ON TABLE}mg;
+ }
+
if ($old_version < 14)
{
# Remove mentions of extended hash functions.
diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out
index a666d89ef5..4d40a6809a 100644
--- a/src/test/regress/expected/cluster.out
+++ b/src/test/regress/expected/cluster.out
@@ -353,7 +353,9 @@ INSERT INTO clstr_3 VALUES (1);
-- this user can only cluster clstr_1 and clstr_3, but the latter
-- has not been clustered
SET SESSION AUTHORIZATION regress_clstr_user;
+SET client_min_messages = ERROR; -- order of "skipping" warnings may vary
CLUSTER;
+RESET client_min_messages;
SELECT * FROM clstr_1 UNION ALL
SELECT * FROM clstr_2 UNION ALL
SELECT * FROM clstr_3;
@@ -501,12 +503,17 @@ CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
CREATE ROLE regress_ptnowner;
CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+CLUSTER ptnowner USING ptnowner_i_idx;
+ERROR: permission denied for table ptnowner
+RESET SESSION AUTHORIZATION;
ALTER TABLE ptnowner OWNER TO regress_ptnowner;
CREATE TEMP TABLE ptnowner_oldnodes AS
SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
JOIN pg_class AS c ON c.oid=tree.relid;
SET SESSION AUTHORIZATION regress_ptnowner;
CLUSTER ptnowner USING ptnowner_i_idx;
+WARNING: permission denied to cluster "ptnowner2", skipping it
RESET SESSION AUTHORIZATION;
SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a
JOIN ptnowner_oldnodes b USING (oid) ORDER BY a.relname COLLATE "C";
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 79fa117cb5..70ab47a92f 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2832,9 +2832,9 @@ RESET ROLE;
GRANT USAGE ON SCHEMA pg_toast TO regress_reindexuser;
SET SESSION ROLE regress_reindexuser;
REINDEX TABLE pg_toast.pg_toast_1260;
-ERROR: must be owner of table pg_toast_1260
+ERROR: permission denied for table pg_toast_1260
REINDEX INDEX pg_toast.pg_toast_1260_index;
-ERROR: must be owner of index pg_toast_1260_index
+ERROR: permission denied for index pg_toast_1260_index
-- Clean up
RESET ROLE;
REVOKE USAGE ON SCHEMA pg_toast FROM regress_reindexuser;
diff --git a/src/test/regress/expected/dependency.out b/src/test/regress/expected/dependency.out
index 5a9ee5d2cd..74d9ff2998 100644
--- a/src/test/regress/expected/dependency.out
+++ b/src/test/regress/expected/dependency.out
@@ -19,7 +19,7 @@ DETAIL: privileges for table deptest
REVOKE SELECT ON deptest FROM GROUP regress_dep_group;
DROP GROUP regress_dep_group;
-- can't drop the user if we revoke the privileges partially
-REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ON deptest FROM regress_dep_user;
+REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, MAINTAIN ON deptest FROM regress_dep_user;
DROP USER regress_dep_user;
ERROR: role "regress_dep_user" cannot be dropped because some objects depend on it
DETAIL: privileges for table deptest
@@ -67,21 +67,21 @@ CREATE TABLE deptest (a serial primary key, b text);
GRANT ALL ON deptest1 TO regress_dep_user2;
RESET SESSION AUTHORIZATION;
\z deptest1
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+----------+-------+----------------------------------------------------+-------------------+----------
- public | deptest1 | table | regress_dep_user0=arwdDxt/regress_dep_user0 +| |
- | | | regress_dep_user1=a*r*w*d*D*x*t*/regress_dep_user0+| |
- | | | regress_dep_user2=arwdDxt/regress_dep_user1 | |
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+----------+-------+------------------------------------------------------+-------------------+----------
+ public | deptest1 | table | regress_dep_user0=arwdDxtm/regress_dep_user0 +| |
+ | | | regress_dep_user1=a*r*w*d*D*x*t*m*/regress_dep_user0+| |
+ | | | regress_dep_user2=arwdDxtm/regress_dep_user1 | |
(1 row)
DROP OWNED BY regress_dep_user1;
-- all grants revoked
\z deptest1
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+----------+-------+---------------------------------------------+-------------------+----------
- public | deptest1 | table | regress_dep_user0=arwdDxt/regress_dep_user0 | |
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+----------+-------+----------------------------------------------+-------------------+----------
+ public | deptest1 | table | regress_dep_user0=arwdDxtm/regress_dep_user0 | |
(1 row)
-- table was dropped
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index fbb0489a4f..d702a9b6e0 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -2296,9 +2296,9 @@ SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem');
(1 row)
SELECT * FROM pg_input_error_info('regress_priv_user1=rY', 'aclitem');
- message | detail | hint | sql_error_code
----------------------------------------------------------+--------+------+----------------
- invalid mode character: must be one of "arwdDxtXUCTcsA" | | | 22P02
+ message | detail | hint | sql_error_code
+----------------------------------------------------------+--------+------+----------------
+ invalid mode character: must be one of "arwdDxtXUCTcsAm" | | | 22P02
(1 row)
--
@@ -2639,38 +2639,38 @@ set session role regress_priv_user4;
grant select on dep_priv_test to regress_priv_user5;
\dp dep_priv_test
Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------------------+-------------------+----------
- public | dep_priv_test | table | regress_priv_user1=arwdDxt/regress_priv_user1+| |
- | | | regress_priv_user2=r*/regress_priv_user1 +| |
- | | | regress_priv_user3=r*/regress_priv_user1 +| |
- | | | regress_priv_user4=r*/regress_priv_user2 +| |
- | | | regress_priv_user4=r*/regress_priv_user3 +| |
- | | | regress_priv_user5=r/regress_priv_user4 | |
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------------+-------+------------------------------------------------+-------------------+----------
+ public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
+ | | | regress_priv_user2=r*/regress_priv_user1 +| |
+ | | | regress_priv_user3=r*/regress_priv_user1 +| |
+ | | | regress_priv_user4=r*/regress_priv_user2 +| |
+ | | | regress_priv_user4=r*/regress_priv_user3 +| |
+ | | | regress_priv_user5=r/regress_priv_user4 | |
(1 row)
set session role regress_priv_user2;
revoke select on dep_priv_test from regress_priv_user4 cascade;
\dp dep_priv_test
Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------------------+-------------------+----------
- public | dep_priv_test | table | regress_priv_user1=arwdDxt/regress_priv_user1+| |
- | | | regress_priv_user2=r*/regress_priv_user1 +| |
- | | | regress_priv_user3=r*/regress_priv_user1 +| |
- | | | regress_priv_user4=r*/regress_priv_user3 +| |
- | | | regress_priv_user5=r/regress_priv_user4 | |
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------------+-------+------------------------------------------------+-------------------+----------
+ public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
+ | | | regress_priv_user2=r*/regress_priv_user1 +| |
+ | | | regress_priv_user3=r*/regress_priv_user1 +| |
+ | | | regress_priv_user4=r*/regress_priv_user3 +| |
+ | | | regress_priv_user5=r/regress_priv_user4 | |
(1 row)
set session role regress_priv_user3;
revoke select on dep_priv_test from regress_priv_user4 cascade;
\dp dep_priv_test
Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------+---------------+-------+-----------------------------------------------+-------------------+----------
- public | dep_priv_test | table | regress_priv_user1=arwdDxt/regress_priv_user1+| |
- | | | regress_priv_user2=r*/regress_priv_user1 +| |
- | | | regress_priv_user3=r*/regress_priv_user1 | |
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------------+-------+------------------------------------------------+-------------------+----------
+ public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
+ | | | regress_priv_user2=r*/regress_priv_user1 +| |
+ | | | regress_priv_user3=r*/regress_priv_user1 | |
(1 row)
set session role regress_priv_user1;
@@ -2800,6 +2800,20 @@ LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+-- LOCK TABLE and MAINTAIN permission
+GRANT MAINTAIN ON lock_table TO regress_locktable_user;
+SET SESSION AUTHORIZATION regress_locktable_user;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
+LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
+COMMIT;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
+COMMIT;
+\c
+REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
-- clean up
DROP TABLE lock_table;
DROP USER regress_locktable_user;
@@ -2913,3 +2927,59 @@ DROP SCHEMA regress_roleoption;
DROP ROLE regress_roleoption_protagonist;
DROP ROLE regress_roleoption_donor;
DROP ROLE regress_roleoption_recipient;
+-- MAINTAIN
+CREATE ROLE regress_no_maintain;
+CREATE ROLE regress_maintain;
+CREATE ROLE regress_maintain_all IN ROLE pg_maintain;
+CREATE TABLE maintain_test (a INT);
+CREATE INDEX ON maintain_test (a);
+GRANT MAINTAIN ON maintain_test TO regress_maintain;
+CREATE MATERIALIZED VIEW refresh_test AS SELECT 1;
+GRANT MAINTAIN ON refresh_test TO regress_maintain;
+CREATE SCHEMA reindex_test;
+-- negative tests; should fail
+SET ROLE regress_no_maintain;
+VACUUM maintain_test;
+WARNING: permission denied to vacuum "maintain_test", skipping it
+ANALYZE maintain_test;
+WARNING: permission denied to analyze "maintain_test", skipping it
+VACUUM (ANALYZE) maintain_test;
+WARNING: permission denied to vacuum "maintain_test", skipping it
+CLUSTER maintain_test USING maintain_test_a_idx;
+ERROR: permission denied for table maintain_test
+REFRESH MATERIALIZED VIEW refresh_test;
+ERROR: permission denied for table refresh_test
+REINDEX TABLE maintain_test;
+ERROR: permission denied for table maintain_test
+REINDEX INDEX maintain_test_a_idx;
+ERROR: permission denied for index maintain_test_a_idx
+REINDEX SCHEMA reindex_test;
+ERROR: must be owner of schema reindex_test
+RESET ROLE;
+SET ROLE regress_maintain;
+VACUUM maintain_test;
+ANALYZE maintain_test;
+VACUUM (ANALYZE) maintain_test;
+CLUSTER maintain_test USING maintain_test_a_idx;
+REFRESH MATERIALIZED VIEW refresh_test;
+REINDEX TABLE maintain_test;
+REINDEX INDEX maintain_test_a_idx;
+REINDEX SCHEMA reindex_test;
+ERROR: must be owner of schema reindex_test
+RESET ROLE;
+SET ROLE regress_maintain_all;
+VACUUM maintain_test;
+ANALYZE maintain_test;
+VACUUM (ANALYZE) maintain_test;
+CLUSTER maintain_test USING maintain_test_a_idx;
+REFRESH MATERIALIZED VIEW refresh_test;
+REINDEX TABLE maintain_test;
+REINDEX INDEX maintain_test_a_idx;
+REINDEX SCHEMA reindex_test;
+RESET ROLE;
+DROP TABLE maintain_test;
+DROP MATERIALIZED VIEW refresh_test;
+DROP SCHEMA reindex_test;
+DROP ROLE regress_no_maintain;
+DROP ROLE regress_maintain;
+DROP ROLE regress_maintain_all;
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 6988128aa4..4538f0c37d 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -93,23 +93,23 @@ CREATE POLICY p2r ON document AS RESTRICTIVE TO regress_rls_dave
CREATE POLICY p1r ON document AS RESTRICTIVE TO regress_rls_dave
USING (cid <> 44);
\dp
- Access privileges
- Schema | Name | Type | Access privileges | Column privileges | Policies
---------------------+----------+-------+---------------------------------------------+-------------------+--------------------------------------------
- regress_rls_schema | category | table | regress_rls_alice=arwdDxt/regress_rls_alice+| |
- | | | =arwdDxt/regress_rls_alice | |
- regress_rls_schema | document | table | regress_rls_alice=arwdDxt/regress_rls_alice+| | p1: +
- | | | =arwdDxt/regress_rls_alice | | (u): (dlevel <= ( SELECT uaccount.seclv +
- | | | | | FROM uaccount +
- | | | | | WHERE (uaccount.pguser = CURRENT_USER)))+
- | | | | | p2r (RESTRICTIVE): +
- | | | | | (u): ((cid <> 44) AND (cid < 50)) +
- | | | | | to: regress_rls_dave +
- | | | | | p1r (RESTRICTIVE): +
- | | | | | (u): (cid <> 44) +
- | | | | | to: regress_rls_dave
- regress_rls_schema | uaccount | table | regress_rls_alice=arwdDxt/regress_rls_alice+| |
- | | | =r/regress_rls_alice | |
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------------------+----------+-------+----------------------------------------------+-------------------+--------------------------------------------
+ regress_rls_schema | category | table | regress_rls_alice=arwdDxtm/regress_rls_alice+| |
+ | | | =arwdDxtm/regress_rls_alice | |
+ regress_rls_schema | document | table | regress_rls_alice=arwdDxtm/regress_rls_alice+| | p1: +
+ | | | =arwdDxtm/regress_rls_alice | | (u): (dlevel <= ( SELECT uaccount.seclv +
+ | | | | | FROM uaccount +
+ | | | | | WHERE (uaccount.pguser = CURRENT_USER)))+
+ | | | | | p2r (RESTRICTIVE): +
+ | | | | | (u): ((cid <> 44) AND (cid < 50)) +
+ | | | | | to: regress_rls_dave +
+ | | | | | p1r (RESTRICTIVE): +
+ | | | | | (u): (cid <> 44) +
+ | | | | | to: regress_rls_dave
+ regress_rls_schema | uaccount | table | regress_rls_alice=arwdDxtm/regress_rls_alice+| |
+ | | | =r/regress_rls_alice | |
(3 rows)
\d document
diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql
index 6cb9c926c0..b7115f8610 100644
--- a/src/test/regress/sql/cluster.sql
+++ b/src/test/regress/sql/cluster.sql
@@ -145,7 +145,9 @@ INSERT INTO clstr_3 VALUES (1);
-- this user can only cluster clstr_1 and clstr_3, but the latter
-- has not been clustered
SET SESSION AUTHORIZATION regress_clstr_user;
+SET client_min_messages = ERROR; -- order of "skipping" warnings may vary
CLUSTER;
+RESET client_min_messages;
SELECT * FROM clstr_1 UNION ALL
SELECT * FROM clstr_2 UNION ALL
SELECT * FROM clstr_3;
@@ -236,6 +238,9 @@ CREATE TABLE ptnowner1 PARTITION OF ptnowner FOR VALUES IN (1);
CREATE ROLE regress_ptnowner;
CREATE TABLE ptnowner2 PARTITION OF ptnowner FOR VALUES IN (2);
ALTER TABLE ptnowner1 OWNER TO regress_ptnowner;
+SET SESSION AUTHORIZATION regress_ptnowner;
+CLUSTER ptnowner USING ptnowner_i_idx;
+RESET SESSION AUTHORIZATION;
ALTER TABLE ptnowner OWNER TO regress_ptnowner;
CREATE TEMP TABLE ptnowner_oldnodes AS
SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree
diff --git a/src/test/regress/sql/dependency.sql b/src/test/regress/sql/dependency.sql
index 2559c62d0b..8d74ed7122 100644
--- a/src/test/regress/sql/dependency.sql
+++ b/src/test/regress/sql/dependency.sql
@@ -21,7 +21,7 @@ REVOKE SELECT ON deptest FROM GROUP regress_dep_group;
DROP GROUP regress_dep_group;
-- can't drop the user if we revoke the privileges partially
-REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES ON deptest FROM regress_dep_user;
+REVOKE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, MAINTAIN ON deptest FROM regress_dep_user;
DROP USER regress_dep_user;
-- now we are OK to drop him
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 3f68cafcd1..323c3f25ce 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -1793,6 +1793,21 @@ COMMIT;
\c
REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
+-- LOCK TABLE and MAINTAIN permission
+GRANT MAINTAIN ON lock_table TO regress_locktable_user;
+SET SESSION AUTHORIZATION regress_locktable_user;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
+ROLLBACK;
+BEGIN;
+LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
+COMMIT;
+BEGIN;
+LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
+COMMIT;
+\c
+REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
+
-- clean up
DROP TABLE lock_table;
DROP USER regress_locktable_user;
@@ -1876,3 +1891,56 @@ DROP SCHEMA regress_roleoption;
DROP ROLE regress_roleoption_protagonist;
DROP ROLE regress_roleoption_donor;
DROP ROLE regress_roleoption_recipient;
+
+-- MAINTAIN
+CREATE ROLE regress_no_maintain;
+CREATE ROLE regress_maintain;
+CREATE ROLE regress_maintain_all IN ROLE pg_maintain;
+
+CREATE TABLE maintain_test (a INT);
+CREATE INDEX ON maintain_test (a);
+GRANT MAINTAIN ON maintain_test TO regress_maintain;
+CREATE MATERIALIZED VIEW refresh_test AS SELECT 1;
+GRANT MAINTAIN ON refresh_test TO regress_maintain;
+CREATE SCHEMA reindex_test;
+
+-- negative tests; should fail
+SET ROLE regress_no_maintain;
+VACUUM maintain_test;
+ANALYZE maintain_test;
+VACUUM (ANALYZE) maintain_test;
+CLUSTER maintain_test USING maintain_test_a_idx;
+REFRESH MATERIALIZED VIEW refresh_test;
+REINDEX TABLE maintain_test;
+REINDEX INDEX maintain_test_a_idx;
+REINDEX SCHEMA reindex_test;
+RESET ROLE;
+
+SET ROLE regress_maintain;
+VACUUM maintain_test;
+ANALYZE maintain_test;
+VACUUM (ANALYZE) maintain_test;
+CLUSTER maintain_test USING maintain_test_a_idx;
+REFRESH MATERIALIZED VIEW refresh_test;
+REINDEX TABLE maintain_test;
+REINDEX INDEX maintain_test_a_idx;
+REINDEX SCHEMA reindex_test;
+RESET ROLE;
+
+SET ROLE regress_maintain_all;
+VACUUM maintain_test;
+ANALYZE maintain_test;
+VACUUM (ANALYZE) maintain_test;
+CLUSTER maintain_test USING maintain_test_a_idx;
+REFRESH MATERIALIZED VIEW refresh_test;
+REINDEX TABLE maintain_test;
+REINDEX INDEX maintain_test_a_idx;
+REINDEX SCHEMA reindex_test;
+RESET ROLE;
+
+DROP TABLE maintain_test;
+DROP MATERIALIZED VIEW refresh_test;
+DROP SCHEMA reindex_test;
+DROP ROLE regress_no_maintain;
+DROP ROLE regress_maintain;
+DROP ROLE regress_maintain_all;
--
2.25.1
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-17 00:03 Jeff Davis <[email protected]>
parent: Nathan Bossart <[email protected]>
1 sibling, 1 reply; 30+ messages in thread
From: Jeff Davis @ 2024-02-17 00:03 UTC (permalink / raw)
To: Nathan Bossart <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
On Wed, 2024-02-14 at 13:02 -0600, Nathan Bossart wrote:
> This seemed like the approach folks were most in favor of at the
> developer
> meeting a couple weeks ago [0]. At least, that was my interpretation
> of
> the discussion.
Attached rebased version.
Note the changes in amcheck. It's creating functions and calling those
functions from the comparators, and so the comparators need to set the
search_path. I don't think that's terribly common, but does represent a
behavior change and could break something.
Regards,
Jef Davis
Attachments:
[text/x-patch] v4-0001-Fix-search_path-to-a-safe-value-during-maintenanc.patch (26.2K, ../../[email protected]/2-v4-0001-Fix-search_path-to-a-safe-value-during-maintenanc.patch)
download | inline diff:
From 6f399aa46fb97e73ad88eac90fe53d7e19c88f2b Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Fri, 16 Feb 2024 14:04:23 -0800
Subject: [PATCH v4] Fix search_path to a safe value during maintenance
operations.
While executing maintenance operations (ANALYZE, CLUSTER, REFRESH
MATERIALIZED VIEW, REINDEX, or VACUUM), set search_path to
'pg_catalog, pg_temp' to prevent inconsistent behavior.
Functions that are used for functional indexes, in index expressions,
or in materialized views and depend on a different search path must be
declared with CREATE FUNCTION ... SET search_path='...'.
This change was previously committed as 05e1737351, then reverted in
commit 2fcc7ee7af because it was too late in the cycle.
Preparation for the MAINTAIN privilege, which was previously reverted
due to search_path manipulation hazards.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/E1q7j7Y-000z1H-Hr%40gemulon.postgresql.org
Discussion: https://postgr.es/m/e44327179e5c9015c8dda67351c04da552066017.camel%40j-davis.com
Reviewed-by: Greg Stark
Reviewed-by: Nathan Bossart
---
contrib/amcheck/t/004_verify_nbtree_unique.pl | 33 +++++++++++--------
contrib/amcheck/verify_nbtree.c | 2 ++
src/backend/access/brin/brin.c | 2 ++
src/backend/catalog/index.c | 8 +++++
src/backend/catalog/namespace.c | 10 +++---
src/backend/commands/analyze.c | 2 ++
src/backend/commands/cluster.c | 2 ++
src/backend/commands/indexcmds.c | 6 ++++
src/backend/commands/matview.c | 2 ++
src/backend/commands/vacuum.c | 2 ++
src/bin/scripts/t/100_vacuumdb.pl | 4 ---
src/include/utils/guc.h | 6 ++++
.../test_oat_hooks/expected/alter_table.out | 2 ++
.../expected/test_oat_hooks.out | 4 +++
src/test/regress/expected/matview.out | 4 ++-
src/test/regress/expected/privileges.out | 12 +++----
src/test/regress/expected/vacuum.out | 2 +-
src/test/regress/sql/matview.sql | 4 ++-
src/test/regress/sql/privileges.sql | 8 ++---
src/test/regress/sql/vacuum.sql | 2 +-
20 files changed, 81 insertions(+), 36 deletions(-)
diff --git a/contrib/amcheck/t/004_verify_nbtree_unique.pl b/contrib/amcheck/t/004_verify_nbtree_unique.pl
index 3f474a158a..4b704e6815 100644
--- a/contrib/amcheck/t/004_verify_nbtree_unique.pl
+++ b/contrib/amcheck/t/004_verify_nbtree_unique.pl
@@ -20,8 +20,11 @@ $node->safe_psql(
'postgres', q(
CREATE EXTENSION amcheck;
+ CREATE SCHEMA test_amcheck;
+ SET search_path = test_amcheck;
+
CREATE FUNCTION ok_cmp (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN $1 < $2 THEN -1
@@ -34,7 +37,7 @@ $node->safe_psql(
--- Check 1: uniqueness violation.
---
CREATE FUNCTION ok_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
@@ -43,7 +46,7 @@ $node->safe_psql(
--- Make values 768 and 769 look equal.
---
CREATE FUNCTION bad_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN ($1 = 768 AND $2 = 769) OR
@@ -56,13 +59,13 @@ $node->safe_psql(
--- Check 2: uniqueness violation without deduplication.
---
CREATE FUNCTION ok_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN $1 = $2 AND $1 = 400 THEN -1
@@ -74,13 +77,13 @@ $node->safe_psql(
--- Check 3: uniqueness violation with deduplication.
---
CREATE FUNCTION ok_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT bad_cmp2($1, $2);
$$;
@@ -142,7 +145,7 @@ my ($result, $stdout, $stderr);
# We have not yet broken the index, so we should get no corruption
$result = $node->safe_psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx1', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
));
is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
@@ -150,6 +153,7 @@ is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
# values to be equal.
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'bad_cmp1'::regproc
WHERE amproc = 'ok_cmp1'::regproc;
@@ -157,7 +161,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx1', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
'detected uniqueness violation for index "bttest_unique_idx1"');
@@ -175,13 +179,14 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx2', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx2"/,
'detected item order invariant violation for index "bttest_unique_idx2"');
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp2'::regproc
WHERE amproc = 'bad_cmp2'::regproc;
@@ -189,7 +194,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx2', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
'detected uniqueness violation for index "bttest_unique_idx2"');
@@ -206,7 +211,7 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx3', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
'detected item order invariant violation for index "bttest_unique_idx3"');
@@ -215,6 +220,7 @@ ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
# with different visibility.
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
DELETE FROM bttest_unique3 WHERE 380 <= i AND i <= 420;
INSERT INTO bttest_unique3 (SELECT * FROM generate_series(380, 420));
INSERT INTO bttest_unique3 VALUES (400);
@@ -228,6 +234,7 @@ $node->safe_psql(
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp3'::regproc
WHERE amproc = 'bad_cmp3'::regproc;
@@ -235,7 +242,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx3', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx3"/,
'detected uniqueness violation for index "bttest_unique_idx3"');
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 91caa53dd8..bff8c61262 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -313,6 +313,8 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
SetUserIdAndSecContext(heaprel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
}
else
{
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 1087a9011e..d1854c2a1c 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -1412,6 +1412,8 @@ brin_summarize_range(PG_FUNCTION_ARGS)
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
}
else
{
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 4b88a9cb87..2203ce7152 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1469,6 +1469,8 @@ index_concurrently_build(Oid heapRelationId,
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
indexRelation = index_open(indexRelationId, RowExclusiveLock);
@@ -3021,6 +3023,8 @@ index_build(Relation heapRelation,
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* Set up initial progress report status */
{
@@ -3356,6 +3360,8 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
indexRelation = index_open(indexId, RowExclusiveLock);
@@ -3617,6 +3623,8 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
if (progress)
{
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 8df30b2440..da0380a3c0 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -4717,6 +4717,11 @@ assign_search_path(const char *newval, void *extra)
void
InitializeSearchPath(void)
{
+ /* Make the context we'll keep search path cache hashtable in */
+ SearchPathCacheContext = AllocSetContextCreate(TopMemoryContext,
+ "search_path processing cache",
+ ALLOCSET_DEFAULT_SIZES);
+
if (IsBootstrapProcessingMode())
{
/*
@@ -4739,11 +4744,6 @@ InitializeSearchPath(void)
}
else
{
- /* Make the context we'll keep search path cache hashtable in */
- SearchPathCacheContext = AllocSetContextCreate(TopMemoryContext,
- "search_path processing cache",
- ALLOCSET_DEFAULT_SIZES);
-
/*
* In normal mode, arrange for a callback on any syscache invalidation
* of pg_namespace or pg_authid rows. (Changing a role name may affect
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index a03495d6c9..70ce834c08 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -349,6 +349,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
SetUserIdAndSecContext(onerel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index e2c48ec560..c2666bc386 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -353,6 +353,8 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
SetUserIdAndSecContext(OldHeap->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* Since we may open a new transaction for each relation, we have to check
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 7a87626f5f..562da8653a 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -584,6 +584,8 @@ DefineIndex(Oid tableId,
int root_save_nestlevel;
root_save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* Some callers need us to run with an empty default_tablespace; this is a
@@ -1340,6 +1342,8 @@ DefineIndex(Oid tableId,
SetUserIdAndSecContext(childrel->rd_rel->relowner,
child_save_sec_context | SECURITY_RESTRICTED_OPERATION);
child_save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* Don't try to create indexes on foreign tables, though. Skip
@@ -3881,6 +3885,8 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* determine safety of this index for set_indexsafe_procflags */
idx->safe = (indexRel->rd_indexprs == NIL &&
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 59920ced83..c9046ac5a9 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -178,6 +178,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* Make sure it is a materialized view. */
if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 64da848627..32a1a80954 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2168,6 +2168,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
SetUserIdAndSecContext(rel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* If PROCESS_MAIN is set (the default), it's time to vacuum the main
diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl
index 4ac021534b..0601fde205 100644
--- a/src/bin/scripts/t/100_vacuumdb.pl
+++ b/src/bin/scripts/t/100_vacuumdb.pl
@@ -109,7 +109,6 @@ $node->safe_psql(
CREATE FUNCTION f1(int) RETURNS int LANGUAGE SQL AS 'SELECT f0($1)';
CREATE TABLE funcidx (x int);
INSERT INTO funcidx VALUES (0),(1),(2),(3);
- CREATE INDEX i0 ON funcidx ((f1(x)));
CREATE SCHEMA "Foo";
CREATE TABLE "Foo".bar(id int);
CREATE SCHEMA "Bar";
@@ -117,9 +116,6 @@ $node->safe_psql(
|);
$node->command_ok([qw|vacuumdb -Z --table="need""q(uot"(")x") postgres|],
'column list');
-$node->command_fails(
- [qw|vacuumdb -Zt funcidx postgres|],
- 'unqualified name via functional index');
$node->command_fails(
[ 'vacuumdb', '--analyze', '--table', 'vactable(c)', 'postgres' ],
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 471d53da8f..391d8d0212 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -203,6 +203,12 @@ typedef enum
#define GUC_QUALIFIER_SEPARATOR '.'
+/*
+ * Safe search path when executing code as the table owner, such as during
+ * maintenance operations.
+ */
+#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
+
/*
* Bit values in "flags" of a GUC variable. Note that these don't appear
* on disk, so we can reassign their values freely.
diff --git a/src/test/modules/test_oat_hooks/expected/alter_table.out b/src/test/modules/test_oat_hooks/expected/alter_table.out
index 19adb28ffb..8cbacca2c9 100644
--- a/src/test/modules/test_oat_hooks/expected/alter_table.out
+++ b/src/test/modules/test_oat_hooks/expected/alter_table.out
@@ -62,6 +62,8 @@ BEGIN
END IF;
END; $$;
NOTICE: in process utility: superuser attempting CREATE FUNCTION
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE FUNCTION
diff --git a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
index f80373aecc..effdc49145 100644
--- a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
+++ b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
@@ -89,11 +89,15 @@ NOTICE: in object access: superuser finished create (subId=0x0) [internal]
NOTICE: in process utility: superuser finished CREATE TABLE
CREATE INDEX regress_test_table_t_idx ON regress_test_table (t);
NOTICE: in process utility: superuser attempting CREATE INDEX
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE INDEX
GRANT SELECT ON Table regress_test_table TO public;
NOTICE: in process utility: superuser attempting GRANT
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in process utility: superuser finished GRANT
CREATE FUNCTION regress_test_func (t text) RETURNS text AS $$
SELECT $1;
diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out
index 67a50bde3d..038ab73517 100644
--- a/src/test/regress/expected/matview.out
+++ b/src/test/regress/expected/matview.out
@@ -574,10 +574,11 @@ DROP OWNED BY regress_user_mvtest CASCADE;
DROP ROLE regress_user_mvtest;
-- Concurrent refresh requires a unique index on the materialized
-- view. Test what happens if it's dropped during the refresh.
+SET search_path = mvtest_mvschema, public;
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
RETURNS bool AS $$
BEGIN
- EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
+ EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx';
RETURN true;
END;
$$ LANGUAGE plpgsql;
@@ -588,6 +589,7 @@ CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
ERROR: could not find suitable unique index on materialized view
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
+RESET search_path;
-- make sure that create WITH NO DATA works via SPI
BEGIN;
CREATE FUNCTION mvtest_func()
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index fbb0489a4f..5ae5757bde 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -1769,7 +1769,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS
'GRANT regress_priv_group2 TO regress_sro_user';
CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true';
+ 'DECLARE c CURSOR WITH HOLD FOR SELECT public.unwanted_grant(); SELECT true';
-- REFRESH of this MV will queue a GRANT at end of transaction
CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA;
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1783,12 +1783,12 @@ SET SESSION AUTHORIZATION regress_sro_user;
-- INSERT to this table will queue a GRANT at end of transaction
CREATE TABLE sro_trojan_table ();
CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS
- 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END';
+ 'BEGIN PERFORM public.unwanted_grant(); RETURN NULL; END';
CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table
INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan();
-- Now, REFRESH will issue such an INSERT, queueing the GRANT
CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true';
+ 'INSERT INTO public.sro_trojan_table DEFAULT VALUES; SELECT true';
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot fire deferred trigger within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
@@ -1800,15 +1800,15 @@ BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT;
ERROR: permission denied to grant role "regress_priv_group2"
DETAIL: Only roles with the ADMIN option on role "regress_priv_group2" may grant this role.
CONTEXT: SQL function "unwanted_grant" statement 1
-SQL statement "SELECT unwanted_grant()"
-PL/pgSQL function sro_trojan() line 1 at PERFORM
+SQL statement "SELECT public.unwanted_grant()"
+PL/pgSQL function public.sro_trojan() line 1 at PERFORM
SQL function "mv_action" statement 1
-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions()
SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
IMMUTABLE LANGUAGE plpgsql AS $$
BEGIN
- PERFORM unwanted_grant();
+ PERFORM public.unwanted_grant();
RAISE WARNING 'owned';
RETURN 1;
EXCEPTION WHEN OTHERS THEN
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index 4def90b805..330fcd884c 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -64,7 +64,7 @@ CLUSTER vaccluster;
CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL
AS 'ANALYZE pg_am';
CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL
- AS 'SELECT $1 FROM do_analyze()';
+ AS 'SELECT $1 FROM public.do_analyze()';
CREATE INDEX ON vaccluster(wrap_do_analyze(i));
INSERT INTO vaccluster VALUES (1), (2);
ANALYZE vaccluster;
diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql
index 235123de1e..b74ee305e0 100644
--- a/src/test/regress/sql/matview.sql
+++ b/src/test/regress/sql/matview.sql
@@ -233,10 +233,11 @@ DROP ROLE regress_user_mvtest;
-- Concurrent refresh requires a unique index on the materialized
-- view. Test what happens if it's dropped during the refresh.
+SET search_path = mvtest_mvschema, public;
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
RETURNS bool AS $$
BEGIN
- EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
+ EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx';
RETURN true;
END;
$$ LANGUAGE plpgsql;
@@ -247,6 +248,7 @@ CREATE MATERIALIZED VIEW drop_idx_matview AS
CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
+RESET search_path;
-- make sure that create WITH NO DATA works via SPI
BEGIN;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 3f68cafcd1..2ef15a9d8c 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -1177,7 +1177,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS
'GRANT regress_priv_group2 TO regress_sro_user';
CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true';
+ 'DECLARE c CURSOR WITH HOLD FOR SELECT public.unwanted_grant(); SELECT true';
-- REFRESH of this MV will queue a GRANT at end of transaction
CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA;
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1188,12 +1188,12 @@ SET SESSION AUTHORIZATION regress_sro_user;
-- INSERT to this table will queue a GRANT at end of transaction
CREATE TABLE sro_trojan_table ();
CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS
- 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END';
+ 'BEGIN PERFORM public.unwanted_grant(); RETURN NULL; END';
CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table
INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan();
-- Now, REFRESH will issue such an INSERT, queueing the GRANT
CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true';
+ 'INSERT INTO public.sro_trojan_table DEFAULT VALUES; SELECT true';
REFRESH MATERIALIZED VIEW sro_mv;
\c -
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1204,7 +1204,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
IMMUTABLE LANGUAGE plpgsql AS $$
BEGIN
- PERFORM unwanted_grant();
+ PERFORM public.unwanted_grant();
RAISE WARNING 'owned';
RETURN 1;
EXCEPTION WHEN OTHERS THEN
diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql
index 51d7b1fecc..0b63ef8dc6 100644
--- a/src/test/regress/sql/vacuum.sql
+++ b/src/test/regress/sql/vacuum.sql
@@ -49,7 +49,7 @@ CLUSTER vaccluster;
CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL
AS 'ANALYZE pg_am';
CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL
- AS 'SELECT $1 FROM do_analyze()';
+ AS 'SELECT $1 FROM public.do_analyze()';
CREATE INDEX ON vaccluster(wrap_do_analyze(i));
INSERT INTO vaccluster VALUES (1), (2);
ANALYZE vaccluster;
--
2.34.1
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-23 21:30 Nathan Bossart <[email protected]>
parent: Jeff Davis <[email protected]>
0 siblings, 1 reply; 30+ messages in thread
From: Nathan Bossart @ 2024-02-23 21:30 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
(Apologies in advance for anything I'm bringing up that we've already
covered somewhere else.)
On Fri, Feb 16, 2024 at 04:03:55PM -0800, Jeff Davis wrote:
> Note the changes in amcheck. It's creating functions and calling those
> functions from the comparators, and so the comparators need to set the
> search_path. I don't think that's terribly common, but does represent a
> behavior change and could break something.
Why is this change needed? Is the idea to make amcheck follow the same
rules as maintenance commands to encourage folks to set up index functions
correctly? Or is amcheck similarly affected by search_path tricks?
> void
> InitializeSearchPath(void)
> {
> + /* Make the context we'll keep search path cache hashtable in */
> + SearchPathCacheContext = AllocSetContextCreate(TopMemoryContext,
> + "search_path processing cache",
> + ALLOCSET_DEFAULT_SIZES);
> +
> if (IsBootstrapProcessingMode())
> {
> /*
> @@ -4739,11 +4744,6 @@ InitializeSearchPath(void)
> }
> else
> {
> - /* Make the context we'll keep search path cache hashtable in */
> - SearchPathCacheContext = AllocSetContextCreate(TopMemoryContext,
> - "search_path processing cache",
> - ALLOCSET_DEFAULT_SIZES);
> -
What is the purpose of this change?
> + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
> + PGC_S_SESSION);
I wonder if it's worth using PGC_S_INTERACTIVE or introducing a new value
for these.
> +/*
> + * Safe search path when executing code as the table owner, such as during
> + * maintenance operations.
> + */
> +#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
Is including pg_temp actually safe? I worry that a user could use their
temporary schema to inject objects that would take the place of
non-schema-qualified stuff in functions.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-28 00:22 Jeff Davis <[email protected]>
parent: Nathan Bossart <[email protected]>
0 siblings, 1 reply; 30+ messages in thread
From: Jeff Davis @ 2024-02-28 00:22 UTC (permalink / raw)
To: Nathan Bossart <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
New version attached.
Do we need a documentation update here? If so, where would be a good
place?
On Fri, 2024-02-23 at 15:30 -0600, Nathan Bossart wrote:
> Why is this change needed? Is the idea to make amcheck follow the
> same
> rules as maintenance commands to encourage folks to set up index
> functions
> correctly?
amcheck is calling functions it defined, so in order to find those
functions it needs to set the right search path.
>
> What is the purpose of this [bootstrap-related] change?
DefineIndex() is called during bootstrap, and it's also a maintenance
command. I tried to handle the bootstrapping case, but I think it's
best to just guard it with a conditional. Done.
I also added Assert(!IsBootstrapProcessingMode()) in
assign_search_path().
> > + SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH,
> > PGC_USERSET,
> > + PGC_S_SESSION);
>
> I wonder if it's worth using PGC_S_INTERACTIVE or introducing a new
> value
> for these.
> >
Did you have a particular concern about PGC_S_SESSION?
If it's less than PGC_S_SESSION, it won't work, because the caller's
SET command will override it, and the same manipulation is possible.
And I don't think we want it higher than PGC_S_SESSION, otherwise the
function can't set its own search_path, if needed.
> > +#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
>
> Is including pg_temp actually safe? I worry that a user could use
> their
> temporary schema to inject objects that would take the place of
> non-schema-qualified stuff in functions.
pg_temp cannot (currently) be excluded. If it is omitted from the
string, it will be placed *first* in the search_path, which is more
dangerous.
pg_temp does not take part in function or operator resolution, which
makes it safer than it first appears. There are potentially some risks
around tables, but it's not typical to access a table in a function
called as part of an index expression.
If we determine that pg_temp is actually unsafe to include, we need to
do something like what I proposed here:
https://www.postgresql.org/message-id/[email protected]
before this change.
Regards,
Jeff Davis
Attachments:
[text/x-patch] v5-0001-Fix-search_path-to-a-safe-value-during-maintenanc.patch (25.9K, ../../[email protected]/2-v5-0001-Fix-search_path-to-a-safe-value-during-maintenanc.patch)
download | inline diff:
From d628e1b4e2632a7f853e2c1f016758569eaee14e Mon Sep 17 00:00:00 2001
From: Jeff Davis <[email protected]>
Date: Fri, 16 Feb 2024 14:04:23 -0800
Subject: [PATCH v5] Fix search_path to a safe value during maintenance
operations.
While executing maintenance operations (ANALYZE, CLUSTER, REFRESH
MATERIALIZED VIEW, REINDEX, or VACUUM), set search_path to
'pg_catalog, pg_temp' to prevent inconsistent behavior.
Functions that are used for functional indexes, in index expressions,
or in materialized views and depend on a different search path must be
declared with CREATE FUNCTION ... SET search_path='...'.
This change was previously committed as 05e1737351, then reverted in
commit 2fcc7ee7af because it was too late in the cycle.
Preparation for the MAINTAIN privilege, which was previously reverted
due to search_path manipulation hazards.
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/E1q7j7Y-000z1H-Hr%40gemulon.postgresql.org
Discussion: https://postgr.es/m/e44327179e5c9015c8dda67351c04da552066017.camel%40j-davis.com
Reviewed-by: Greg Stark
Reviewed-by: Nathan Bossart
---
contrib/amcheck/t/004_verify_nbtree_unique.pl | 33 +++++++++++--------
contrib/amcheck/verify_nbtree.c | 2 ++
src/backend/access/brin/brin.c | 2 ++
src/backend/catalog/index.c | 9 +++++
src/backend/catalog/namespace.c | 3 ++
src/backend/commands/analyze.c | 2 ++
src/backend/commands/cluster.c | 2 ++
src/backend/commands/indexcmds.c | 8 +++++
src/backend/commands/matview.c | 2 ++
src/backend/commands/vacuum.c | 2 ++
src/bin/scripts/t/100_vacuumdb.pl | 4 ---
src/include/utils/guc.h | 6 ++++
.../test_oat_hooks/expected/alter_table.out | 2 ++
.../expected/test_oat_hooks.out | 4 +++
src/test/regress/expected/matview.out | 4 ++-
src/test/regress/expected/privileges.out | 12 +++----
src/test/regress/expected/vacuum.out | 2 +-
src/test/regress/sql/matview.sql | 4 ++-
src/test/regress/sql/privileges.sql | 8 ++---
src/test/regress/sql/vacuum.sql | 2 +-
20 files changed, 82 insertions(+), 31 deletions(-)
diff --git a/contrib/amcheck/t/004_verify_nbtree_unique.pl b/contrib/amcheck/t/004_verify_nbtree_unique.pl
index 3f474a158a..4b704e6815 100644
--- a/contrib/amcheck/t/004_verify_nbtree_unique.pl
+++ b/contrib/amcheck/t/004_verify_nbtree_unique.pl
@@ -20,8 +20,11 @@ $node->safe_psql(
'postgres', q(
CREATE EXTENSION amcheck;
+ CREATE SCHEMA test_amcheck;
+ SET search_path = test_amcheck;
+
CREATE FUNCTION ok_cmp (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN $1 < $2 THEN -1
@@ -34,7 +37,7 @@ $node->safe_psql(
--- Check 1: uniqueness violation.
---
CREATE FUNCTION ok_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
@@ -43,7 +46,7 @@ $node->safe_psql(
--- Make values 768 and 769 look equal.
---
CREATE FUNCTION bad_cmp1 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN ($1 = 768 AND $2 = 769) OR
@@ -56,13 +59,13 @@ $node->safe_psql(
--- Check 2: uniqueness violation without deduplication.
---
CREATE FUNCTION ok_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp2 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT
CASE WHEN $1 = $2 AND $1 = 400 THEN -1
@@ -74,13 +77,13 @@ $node->safe_psql(
--- Check 3: uniqueness violation with deduplication.
---
CREATE FUNCTION ok_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT ok_cmp($1, $2);
$$;
CREATE FUNCTION bad_cmp3 (int4, int4)
- RETURNS int LANGUAGE sql AS
+ RETURNS int LANGUAGE sql SET search_path = test_amcheck AS
$$
SELECT bad_cmp2($1, $2);
$$;
@@ -142,7 +145,7 @@ my ($result, $stdout, $stderr);
# We have not yet broken the index, so we should get no corruption
$result = $node->safe_psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx1', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
));
is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
@@ -150,6 +153,7 @@ is($result, '', 'run amcheck on non-broken bttest_unique_idx1');
# values to be equal.
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'bad_cmp1'::regproc
WHERE amproc = 'ok_cmp1'::regproc;
@@ -157,7 +161,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx1', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx1', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
'detected uniqueness violation for index "bttest_unique_idx1"');
@@ -175,13 +179,14 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx1"/,
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx2', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx2"/,
'detected item order invariant violation for index "bttest_unique_idx2"');
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp2'::regproc
WHERE amproc = 'bad_cmp2'::regproc;
@@ -189,7 +194,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx2', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx2', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
'detected uniqueness violation for index "bttest_unique_idx2"');
@@ -206,7 +211,7 @@ ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx2"/,
# but no uniqueness violation.
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx3', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
));
ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
'detected item order invariant violation for index "bttest_unique_idx3"');
@@ -215,6 +220,7 @@ ok( $stderr =~ /item order invariant violated for index "bttest_unique_idx3"/,
# with different visibility.
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
DELETE FROM bttest_unique3 WHERE 380 <= i AND i <= 420;
INSERT INTO bttest_unique3 (SELECT * FROM generate_series(380, 420));
INSERT INTO bttest_unique3 VALUES (400);
@@ -228,6 +234,7 @@ $node->safe_psql(
$node->safe_psql(
'postgres', q(
+ SET search_path = test_amcheck;
UPDATE pg_catalog.pg_amproc SET
amproc = 'ok_cmp3'::regproc
WHERE amproc = 'bad_cmp3'::regproc;
@@ -235,7 +242,7 @@ $node->safe_psql(
($result, $stdout, $stderr) = $node->psql(
'postgres', q(
- SELECT bt_index_check('bttest_unique_idx3', true, true);
+ SELECT bt_index_check('test_amcheck.bttest_unique_idx3', true, true);
));
ok( $stderr =~ /index uniqueness is violated for index "bttest_unique_idx3"/,
'detected uniqueness violation for index "bttest_unique_idx3"');
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 91caa53dd8..bff8c61262 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -313,6 +313,8 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
SetUserIdAndSecContext(heaprel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
}
else
{
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 1087a9011e..d1854c2a1c 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -1412,6 +1412,8 @@ brin_summarize_range(PG_FUNCTION_ARGS)
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
}
else
{
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 4b88a9cb87..53278ec89b 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1469,6 +1469,8 @@ index_concurrently_build(Oid heapRelationId,
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
indexRelation = index_open(indexRelationId, RowExclusiveLock);
@@ -3021,6 +3023,9 @@ index_build(Relation heapRelation,
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ if (!IsBootstrapProcessingMode())
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* Set up initial progress report status */
{
@@ -3356,6 +3361,8 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot)
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
indexRelation = index_open(indexId, RowExclusiveLock);
@@ -3617,6 +3624,8 @@ reindex_index(const ReindexStmt *stmt, Oid indexId,
SetUserIdAndSecContext(heapRelation->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
if (progress)
{
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 8df30b2440..a68fdd844b 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -4697,6 +4697,9 @@ check_search_path(char **newval, void **extra, GucSource source)
void
assign_search_path(const char *newval, void *extra)
{
+ /* don't access search_path during bootstrap */
+ Assert(!IsBootstrapProcessingMode());
+
/*
* We mark the path as needing recomputation, but don't do anything until
* it's needed. This avoids trying to do database access during GUC
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index a03495d6c9..70ce834c08 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -349,6 +349,8 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
SetUserIdAndSecContext(onerel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* measure elapsed time iff autovacuum logging requires it */
if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0)
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index e2c48ec560..c2666bc386 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -353,6 +353,8 @@ cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params)
SetUserIdAndSecContext(OldHeap->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* Since we may open a new transaction for each relation, we have to check
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 7a87626f5f..96eb7d346a 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -585,6 +585,10 @@ DefineIndex(Oid tableId,
root_save_nestlevel = NewGUCNestLevel();
+ if (!IsBootstrapProcessingMode())
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
+
/*
* Some callers need us to run with an empty default_tablespace; this is a
* necessary hack to be able to reproduce catalog state accurately when
@@ -1340,6 +1344,8 @@ DefineIndex(Oid tableId,
SetUserIdAndSecContext(childrel->rd_rel->relowner,
child_save_sec_context | SECURITY_RESTRICTED_OPERATION);
child_save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* Don't try to create indexes on foreign tables, though. Skip
@@ -3881,6 +3887,8 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
SetUserIdAndSecContext(heapRel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* determine safety of this index for set_indexsafe_procflags */
idx->safe = (indexRel->rd_indexprs == NIL &&
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 59920ced83..c9046ac5a9 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -178,6 +178,8 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/* Make sure it is a materialized view. */
if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 64da848627..32a1a80954 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2168,6 +2168,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
SetUserIdAndSecContext(rel->rd_rel->relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
save_nestlevel = NewGUCNestLevel();
+ SetConfigOption("search_path", GUC_SAFE_SEARCH_PATH, PGC_USERSET,
+ PGC_S_SESSION);
/*
* If PROCESS_MAIN is set (the default), it's time to vacuum the main
diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl
index 4ac021534b..0601fde205 100644
--- a/src/bin/scripts/t/100_vacuumdb.pl
+++ b/src/bin/scripts/t/100_vacuumdb.pl
@@ -109,7 +109,6 @@ $node->safe_psql(
CREATE FUNCTION f1(int) RETURNS int LANGUAGE SQL AS 'SELECT f0($1)';
CREATE TABLE funcidx (x int);
INSERT INTO funcidx VALUES (0),(1),(2),(3);
- CREATE INDEX i0 ON funcidx ((f1(x)));
CREATE SCHEMA "Foo";
CREATE TABLE "Foo".bar(id int);
CREATE SCHEMA "Bar";
@@ -117,9 +116,6 @@ $node->safe_psql(
|);
$node->command_ok([qw|vacuumdb -Z --table="need""q(uot"(")x") postgres|],
'column list');
-$node->command_fails(
- [qw|vacuumdb -Zt funcidx postgres|],
- 'unqualified name via functional index');
$node->command_fails(
[ 'vacuumdb', '--analyze', '--table', 'vactable(c)', 'postgres' ],
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 471d53da8f..391d8d0212 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -203,6 +203,12 @@ typedef enum
#define GUC_QUALIFIER_SEPARATOR '.'
+/*
+ * Safe search path when executing code as the table owner, such as during
+ * maintenance operations.
+ */
+#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
+
/*
* Bit values in "flags" of a GUC variable. Note that these don't appear
* on disk, so we can reassign their values freely.
diff --git a/src/test/modules/test_oat_hooks/expected/alter_table.out b/src/test/modules/test_oat_hooks/expected/alter_table.out
index 19adb28ffb..8cbacca2c9 100644
--- a/src/test/modules/test_oat_hooks/expected/alter_table.out
+++ b/src/test/modules/test_oat_hooks/expected/alter_table.out
@@ -62,6 +62,8 @@ BEGIN
END IF;
END; $$;
NOTICE: in process utility: superuser attempting CREATE FUNCTION
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE FUNCTION
diff --git a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
index f80373aecc..effdc49145 100644
--- a/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
+++ b/src/test/modules/test_oat_hooks/expected/test_oat_hooks.out
@@ -89,11 +89,15 @@ NOTICE: in object access: superuser finished create (subId=0x0) [internal]
NOTICE: in process utility: superuser finished CREATE TABLE
CREATE INDEX regress_test_table_t_idx ON regress_test_table (t);
NOTICE: in process utility: superuser attempting CREATE INDEX
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in object access: superuser attempting create (subId=0x0) [explicit]
NOTICE: in object access: superuser finished create (subId=0x0) [explicit]
NOTICE: in process utility: superuser finished CREATE INDEX
GRANT SELECT ON Table regress_test_table TO public;
NOTICE: in process utility: superuser attempting GRANT
+NOTICE: in object access: superuser attempting namespace search (subId=0x0) [no report on violation, allowed]
+NOTICE: in object access: superuser finished namespace search (subId=0x0) [no report on violation, allowed]
NOTICE: in process utility: superuser finished GRANT
CREATE FUNCTION regress_test_func (t text) RETURNS text AS $$
SELECT $1;
diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out
index 67a50bde3d..038ab73517 100644
--- a/src/test/regress/expected/matview.out
+++ b/src/test/regress/expected/matview.out
@@ -574,10 +574,11 @@ DROP OWNED BY regress_user_mvtest CASCADE;
DROP ROLE regress_user_mvtest;
-- Concurrent refresh requires a unique index on the materialized
-- view. Test what happens if it's dropped during the refresh.
+SET search_path = mvtest_mvschema, public;
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
RETURNS bool AS $$
BEGIN
- EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
+ EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx';
RETURN true;
END;
$$ LANGUAGE plpgsql;
@@ -588,6 +589,7 @@ CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
ERROR: could not find suitable unique index on materialized view
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
+RESET search_path;
-- make sure that create WITH NO DATA works via SPI
BEGIN;
CREATE FUNCTION mvtest_func()
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index fbb0489a4f..5ae5757bde 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -1769,7 +1769,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS
'GRANT regress_priv_group2 TO regress_sro_user';
CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true';
+ 'DECLARE c CURSOR WITH HOLD FOR SELECT public.unwanted_grant(); SELECT true';
-- REFRESH of this MV will queue a GRANT at end of transaction
CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA;
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1783,12 +1783,12 @@ SET SESSION AUTHORIZATION regress_sro_user;
-- INSERT to this table will queue a GRANT at end of transaction
CREATE TABLE sro_trojan_table ();
CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS
- 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END';
+ 'BEGIN PERFORM public.unwanted_grant(); RETURN NULL; END';
CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table
INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan();
-- Now, REFRESH will issue such an INSERT, queueing the GRANT
CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true';
+ 'INSERT INTO public.sro_trojan_table DEFAULT VALUES; SELECT true';
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot fire deferred trigger within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
@@ -1800,15 +1800,15 @@ BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT;
ERROR: permission denied to grant role "regress_priv_group2"
DETAIL: Only roles with the ADMIN option on role "regress_priv_group2" may grant this role.
CONTEXT: SQL function "unwanted_grant" statement 1
-SQL statement "SELECT unwanted_grant()"
-PL/pgSQL function sro_trojan() line 1 at PERFORM
+SQL statement "SELECT public.unwanted_grant()"
+PL/pgSQL function public.sro_trojan() line 1 at PERFORM
SQL function "mv_action" statement 1
-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions()
SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
IMMUTABLE LANGUAGE plpgsql AS $$
BEGIN
- PERFORM unwanted_grant();
+ PERFORM public.unwanted_grant();
RAISE WARNING 'owned';
RETURN 1;
EXCEPTION WHEN OTHERS THEN
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index 4def90b805..330fcd884c 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -64,7 +64,7 @@ CLUSTER vaccluster;
CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL
AS 'ANALYZE pg_am';
CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL
- AS 'SELECT $1 FROM do_analyze()';
+ AS 'SELECT $1 FROM public.do_analyze()';
CREATE INDEX ON vaccluster(wrap_do_analyze(i));
INSERT INTO vaccluster VALUES (1), (2);
ANALYZE vaccluster;
diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql
index 235123de1e..b74ee305e0 100644
--- a/src/test/regress/sql/matview.sql
+++ b/src/test/regress/sql/matview.sql
@@ -233,10 +233,11 @@ DROP ROLE regress_user_mvtest;
-- Concurrent refresh requires a unique index on the materialized
-- view. Test what happens if it's dropped during the refresh.
+SET search_path = mvtest_mvschema, public;
CREATE OR REPLACE FUNCTION mvtest_drop_the_index()
RETURNS bool AS $$
BEGIN
- EXECUTE 'DROP INDEX IF EXISTS mvtest_drop_idx';
+ EXECUTE 'DROP INDEX IF EXISTS mvtest_mvschema.mvtest_drop_idx';
RETURN true;
END;
$$ LANGUAGE plpgsql;
@@ -247,6 +248,7 @@ CREATE MATERIALIZED VIEW drop_idx_matview AS
CREATE UNIQUE INDEX mvtest_drop_idx ON drop_idx_matview (i);
REFRESH MATERIALIZED VIEW CONCURRENTLY drop_idx_matview;
DROP MATERIALIZED VIEW drop_idx_matview; -- clean up
+RESET search_path;
-- make sure that create WITH NO DATA works via SPI
BEGIN;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 3f68cafcd1..2ef15a9d8c 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -1177,7 +1177,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS
'GRANT regress_priv_group2 TO regress_sro_user';
CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true';
+ 'DECLARE c CURSOR WITH HOLD FOR SELECT public.unwanted_grant(); SELECT true';
-- REFRESH of this MV will queue a GRANT at end of transaction
CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA;
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1188,12 +1188,12 @@ SET SESSION AUTHORIZATION regress_sro_user;
-- INSERT to this table will queue a GRANT at end of transaction
CREATE TABLE sro_trojan_table ();
CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS
- 'BEGIN PERFORM unwanted_grant(); RETURN NULL; END';
+ 'BEGIN PERFORM public.unwanted_grant(); RETURN NULL; END';
CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table
INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan();
-- Now, REFRESH will issue such an INSERT, queueing the GRANT
CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
- 'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true';
+ 'INSERT INTO public.sro_trojan_table DEFAULT VALUES; SELECT true';
REFRESH MATERIALIZED VIEW sro_mv;
\c -
REFRESH MATERIALIZED VIEW sro_mv;
@@ -1204,7 +1204,7 @@ SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
IMMUTABLE LANGUAGE plpgsql AS $$
BEGIN
- PERFORM unwanted_grant();
+ PERFORM public.unwanted_grant();
RAISE WARNING 'owned';
RETURN 1;
EXCEPTION WHEN OTHERS THEN
diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql
index 51d7b1fecc..0b63ef8dc6 100644
--- a/src/test/regress/sql/vacuum.sql
+++ b/src/test/regress/sql/vacuum.sql
@@ -49,7 +49,7 @@ CLUSTER vaccluster;
CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL
AS 'ANALYZE pg_am';
CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL
- AS 'SELECT $1 FROM do_analyze()';
+ AS 'SELECT $1 FROM public.do_analyze()';
CREATE INDEX ON vaccluster(wrap_do_analyze(i));
INSERT INTO vaccluster VALUES (1), (2);
ANALYZE vaccluster;
--
2.34.1
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: MAINTAIN privilege -- what do we need to un-revert it?
@ 2024-02-28 16:55 Nathan Bossart <[email protected]>
parent: Jeff Davis <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Nathan Bossart @ 2024-02-28 16:55 UTC (permalink / raw)
To: Jeff Davis <[email protected]>; +Cc: pgsql-hackers; Joe Conway <[email protected]>; Robert Haas <[email protected]>
On Tue, Feb 27, 2024 at 04:22:34PM -0800, Jeff Davis wrote:
> Do we need a documentation update here? If so, where would be a good
> place?
I'm afraid I don't have a better idea than adding a short note in each
affected commands's page.
> On Fri, 2024-02-23 at 15:30 -0600, Nathan Bossart wrote:
>> I wonder if it's worth using PGC_S_INTERACTIVE or introducing a new
>> value
>> for these.
>
> Did you have a particular concern about PGC_S_SESSION?
My only concern is that it could obscure the source of the search_path
change, which in turn might cause confusion when things fail.
> If it's less than PGC_S_SESSION, it won't work, because the caller's
> SET command will override it, and the same manipulation is possible.
>
> And I don't think we want it higher than PGC_S_SESSION, otherwise the
> function can't set its own search_path, if needed.
Yeah, we would have to make it equivalent in priority to PGC_S_SESSION,
which would likely require a bunch of special logic. I don't know if this
is worth it, and this seems like something that could pretty easily be
added in the future if it became necessary.
>> > +#define GUC_SAFE_SEARCH_PATH "pg_catalog, pg_temp"
>>
>> Is including pg_temp actually safe? I worry that a user could use
>> their
>> temporary schema to inject objects that would take the place of
>> non-schema-qualified stuff in functions.
>
> pg_temp cannot (currently) be excluded. If it is omitted from the
> string, it will be placed *first* in the search_path, which is more
> dangerous.
>
> pg_temp does not take part in function or operator resolution, which
> makes it safer than it first appears. There are potentially some risks
> around tables, but it's not typical to access a table in a function
> called as part of an index expression.
>
> If we determine that pg_temp is actually unsafe to include, we need to
> do something like what I proposed here:
>
> https://www.postgresql.org/message-id/[email protected]
I don't doubt anything you've said, but I can't help but think that we
might as well handle the pg_temp risk, too.
Furthermore, I see that we use "" as a safe search_path for autovacuum and
fe_utils/connect.h. Is there any way to unite these? IIUC it might be
possible to combine the autovacuum and maintenance command cases (i.e.,
"!pg_temp"), but we might need to keep pg_temp for the frontend case. I
think it's worth trying to add comments about why this setting is safe for
some cases but not others, too.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
^ permalink raw reply [nested|flat] 30+ messages in thread
end of thread, other threads:[~2024-02-28 16:55 UTC | newest]
Thread overview: 30+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2017-02-04 23:05 Variable name typo in launcher.c Masahiko Sawada <[email protected]>
2017-02-06 09:46 ` Heikki Linnakangas <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2021-01-09 15:49 [PATCH] fixes to docs and comments Justin Pryzby <[email protected]>
2024-02-14 18:20 MAINTAIN privilege -- what do we need to un-revert it? Jeff Davis <[email protected]>
2024-02-14 19:02 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Nathan Bossart <[email protected]>
2024-02-15 16:14 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Nathan Bossart <[email protected]>
2024-02-17 00:03 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Jeff Davis <[email protected]>
2024-02-23 21:30 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Nathan Bossart <[email protected]>
2024-02-28 00:22 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Jeff Davis <[email protected]>
2024-02-28 16:55 ` Re: MAINTAIN privilege -- what do we need to un-revert it? Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox