summaryrefslogtreecommitdiffstats
path: root/src/interfaces/libpq
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq')
-rw-r--r--src/interfaces/libpq/fe-exec.c73
-rw-r--r--src/interfaces/libpq/fe-protocol3.c9
-rw-r--r--src/interfaces/libpq/fe-secure-gssapi.c62
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c100
-rw-r--r--src/interfaces/libpq/fe-secure.c7
-rw-r--r--src/interfaces/libpq/libpq-int.h7
-rw-r--r--src/interfaces/libpq/po/ru.po230
7 files changed, 274 insertions, 214 deletions
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 8989f71..c9450ec 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -846,6 +846,8 @@ pqSaveWriteError(PGconn *conn)
* using whatever is in conn->errorMessage. In any case, clear the async
* result storage, and update our notion of how much error text has been
* returned to the application.
+ *
+ * Note that in no case (not even OOM) do we return NULL.
*/
PGresult *
pqPrepareAsyncResult(PGconn *conn)
@@ -2119,29 +2121,21 @@ PQgetResult(PGconn *conn)
/*
* We're about to return the NULL that terminates the round of
- * results from the current query; prepare to send the results
- * of the next query, if any, when we're called next. If there's
- * no next element in the command queue, this gets us in IDLE
- * state.
+ * results from the current query; prepare to send the results of
+ * the next query, if any, when we're called next. If there's no
+ * next element in the command queue, this gets us in IDLE state.
*/
pqPipelineProcessQueue(conn);
res = NULL; /* query is complete */
break;
case PGASYNC_READY:
-
- /*
- * For any query type other than simple query protocol, we advance
- * the command queue here. This is because for simple query
- * protocol we can get the READY state multiple times before the
- * command is actually complete, since the command string can
- * contain many queries. In simple query protocol, the queue
- * advance is done by fe-protocol3 when it receives ReadyForQuery.
- */
- if (conn->cmd_queue_head &&
- conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE)
- pqCommandQueueAdvance(conn);
res = pqPrepareAsyncResult(conn);
+
+ /* Advance the queue as appropriate */
+ pqCommandQueueAdvance(conn, false,
+ res->resultStatus == PGRES_PIPELINE_SYNC);
+
if (conn->pipelineStatus != PQ_PIPELINE_OFF)
{
/*
@@ -2161,7 +2155,7 @@ PQgetResult(PGconn *conn)
* (In other words: we don't return a NULL after a pipeline
* sync.)
*/
- if (res && res->resultStatus == PGRES_PIPELINE_SYNC)
+ if (res->resultStatus == PGRES_PIPELINE_SYNC)
pqPipelineProcessQueue(conn);
}
else
@@ -3040,18 +3034,44 @@ PQexitPipelineMode(PGconn *conn)
/*
* pqCommandQueueAdvance
- * Remove one query from the command queue, when we receive
- * all results from the server that pertain to it.
+ * Remove one query from the command queue, if appropriate.
+ *
+ * If we have received all results corresponding to the head element
+ * in the command queue, remove it.
+ *
+ * In simple query protocol we must not advance the command queue until the
+ * ReadyForQuery message has been received. This is because in simple mode a
+ * command can have multiple queries, and we must process result for all of
+ * them before moving on to the next command.
+ *
+ * Another consideration is synchronization during error processing in
+ * extended query protocol: we refuse to advance the queue past a SYNC queue
+ * element, unless the result we've received is also a SYNC. In particular
+ * this protects us from advancing when an error is received at an
+ * inappropriate moment.
*/
void
-pqCommandQueueAdvance(PGconn *conn)
+pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync)
{
PGcmdQueueEntry *prevquery;
if (conn->cmd_queue_head == NULL)
return;
- /* delink from queue */
+ /*
+ * If processing a query of simple query protocol, we only advance the
+ * queue when we receive the ReadyForQuery message for it.
+ */
+ if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery)
+ return;
+
+ /*
+ * If we're waiting for a SYNC, don't advance the queue until we get one.
+ */
+ if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync)
+ return;
+
+ /* delink element from queue */
prevquery = conn->cmd_queue_head;
conn->cmd_queue_head = conn->cmd_queue_head->next;
@@ -3059,7 +3079,7 @@ pqCommandQueueAdvance(PGconn *conn)
if (conn->cmd_queue_head == NULL)
conn->cmd_queue_tail = NULL;
- /* and make it recyclable */
+ /* and make the queue element recyclable */
prevquery->next = NULL;
pqRecycleCmdQueueEntry(conn, prevquery);
}
@@ -3083,6 +3103,7 @@ pqPipelineProcessQueue(PGconn *conn)
return;
case PGASYNC_IDLE:
+
/*
* If we're in IDLE mode and there's some command in the queue,
* get us into PIPELINE_IDLE mode and process normally. Otherwise
@@ -3271,6 +3292,14 @@ PQsendFlushRequest(PGconn *conn)
return 0;
}
+ /*
+ * Give the data a push (in pipeline mode, only if we're past the size
+ * threshold). In nonblock mode, don't complain if we're unable to send
+ * it all; PQgetResult() will do any additional flushing needed.
+ */
+ if (pqPipelineFlush(conn) < 0)
+ return 0;
+
return 1;
}
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 0d60e8c..3870d52 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -240,13 +240,8 @@ pqParseInput3(PGconn *conn)
}
else
{
- /*
- * In simple query protocol, advance the command queue
- * (see PQgetResult).
- */
- if (conn->cmd_queue_head &&
- conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE)
- pqCommandQueueAdvance(conn);
+ /* Advance the command queue and set us idle */
+ pqCommandQueueAdvance(conn, true, false);
conn->asyncStatus = PGASYNC_IDLE;
}
break;
diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c
index 5f9104b..a3768cd 100644
--- a/src/interfaces/libpq/fe-secure-gssapi.c
+++ b/src/interfaces/libpq/fe-secure-gssapi.c
@@ -79,8 +79,8 @@
* On success, returns the number of data bytes consumed (possibly less than
* len). On failure, returns -1 with errno set appropriately. If the errno
* indicates a non-retryable error, a message is added to conn->errorMessage.
- * For retryable errors, caller should call again (passing the same data)
- * once the socket is ready.
+ * For retryable errors, caller should call again (passing the same or more
+ * data) once the socket is ready.
*/
ssize_t
pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
@@ -90,19 +90,25 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
gss_buffer_desc input,
output = GSS_C_EMPTY_BUFFER;
ssize_t ret = -1;
- size_t bytes_sent = 0;
size_t bytes_to_encrypt;
size_t bytes_encrypted;
gss_ctx_id_t gctx = conn->gctx;
/*
- * When we get a failure, we must not tell the caller we have successfully
- * transmitted everything, else it won't retry. Hence a "success"
- * (positive) return value must only count source bytes corresponding to
- * fully-transmitted encrypted packets. The amount of source data
- * corresponding to the current partly-transmitted packet is remembered in
+ * When we get a retryable failure, we must not tell the caller we have
+ * successfully transmitted everything, else it won't retry. For
+ * simplicity, we claim we haven't transmitted anything until we have
+ * successfully transmitted all "len" bytes. Between calls, the amount of
+ * the current input data that's already been encrypted and placed into
+ * PqGSSSendBuffer (and perhaps transmitted) is remembered in
* PqGSSSendConsumed. On a retry, the caller *must* be sending that data
* again, so if it offers a len less than that, something is wrong.
+ *
+ * Note: it may seem attractive to report partial write completion once
+ * we've successfully sent any encrypted packets. However, that can cause
+ * problems for callers; notably, pqPutMsgEnd's heuristic to send only
+ * full 8K blocks interacts badly with such a hack. We won't save much,
+ * typically, by letting callers discard data early, so don't risk it.
*/
if (len < PqGSSSendConsumed)
{
@@ -135,38 +141,25 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
*/
if (PqGSSSendLength)
{
- ssize_t ret;
+ ssize_t retval;
ssize_t amount = PqGSSSendLength - PqGSSSendNext;
- ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount);
- if (ret <= 0)
- {
- /*
- * Report any previously-sent data; if there was none, reflect
- * the pqsecure_raw_write result up to our caller. When there
- * was some, we're effectively assuming that any interesting
- * failure condition will recur on the next try.
- */
- if (bytes_sent)
- return bytes_sent;
- return ret;
- }
+ retval = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendNext, amount);
+ if (retval <= 0)
+ return retval;
/*
* Check if this was a partial write, and if so, move forward that
* far in our buffer and try again.
*/
- if (ret != amount)
+ if (retval < amount)
{
- PqGSSSendNext += ret;
+ PqGSSSendNext += retval;
continue;
}
- /* We've successfully sent whatever data was in that packet. */
- bytes_sent += PqGSSSendConsumed;
-
- /* All encrypted data was sent, our buffer is empty now. */
- PqGSSSendLength = PqGSSSendNext = PqGSSSendConsumed = 0;
+ /* We've successfully sent whatever data was in the buffer. */
+ PqGSSSendLength = PqGSSSendNext = 0;
}
/*
@@ -192,7 +185,7 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
/*
* Create the next encrypted packet. Any failure here is considered a
- * hard failure, so we return -1 even if bytes_sent > 0.
+ * hard failure, so we return -1 even if some data has been sent.
*/
major = gss_wrap(&minor, gctx, 1, GSS_C_QOP_DEFAULT,
&input, &conf_state, &output);
@@ -238,10 +231,13 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
}
/* If we get here, our counters should all match up. */
- Assert(bytes_sent == len);
- Assert(bytes_sent == bytes_encrypted);
+ Assert(len == PqGSSSendConsumed);
+ Assert(len == bytes_encrypted);
+
+ /* We're reporting all the data as sent, so reset PqGSSSendConsumed. */
+ PqGSSSendConsumed = 0;
- ret = bytes_sent;
+ ret = bytes_encrypted;
cleanup:
/* Release GSSAPI buffer storage, if we didn't already */
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index af59ff4..61f3767 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -209,7 +209,7 @@ rloop:
*/
goto rloop;
case SSL_ERROR_SYSCALL:
- if (n < 0)
+ if (n < 0 && SOCK_ERRNO != 0)
{
result_errno = SOCK_ERRNO;
if (result_errno == EPIPE ||
@@ -317,7 +317,13 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
n = 0;
break;
case SSL_ERROR_SYSCALL:
- if (n < 0)
+
+ /*
+ * If errno is still zero then assume it's a read EOF situation,
+ * and report EOF. (This seems possible because SSL_write can
+ * also do reads.)
+ */
+ if (n < 0 && SOCK_ERRNO != 0)
{
result_errno = SOCK_ERRNO;
if (result_errno == EPIPE || result_errno == ECONNRESET)
@@ -1479,10 +1485,12 @@ open_client_SSL(PGconn *conn)
{
int r;
+ SOCK_ERRNO_SET(0);
ERR_clear_error();
r = SSL_connect(conn->ssl);
if (r <= 0)
{
+ int save_errno = SOCK_ERRNO;
int err = SSL_get_error(conn->ssl, r);
unsigned long ecode;
@@ -1499,10 +1507,10 @@ open_client_SSL(PGconn *conn)
{
char sebuf[PG_STRERROR_R_BUFLEN];
- if (r == -1)
+ if (r == -1 && save_errno != 0)
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: %s\n"),
- SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ SOCK_STRERROR(save_errno, sebuf, sizeof(sebuf)));
else
appendPQExpBufferStr(&conn->errorMessage,
libpq_gettext("SSL SYSCALL error: EOF detected\n"));
@@ -1800,11 +1808,7 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
* to retry; do we need to adopt their logic for that?
*/
-#ifndef HAVE_BIO_GET_DATA
-#define BIO_get_data(bio) (bio->ptr)
-#define BIO_set_data(bio, data) (bio->ptr = data)
-#endif
-
+/* protected by ssl_config_mutex */
static BIO_METHOD *my_bio_methods;
static int
@@ -1812,7 +1816,7 @@ my_sock_read(BIO *h, char *buf, int size)
{
int res;
- res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
+ res = pqsecure_raw_read((PGconn *) BIO_get_app_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res < 0)
{
@@ -1842,7 +1846,7 @@ my_sock_write(BIO *h, const char *buf, int size)
{
int res;
- res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
+ res = pqsecure_raw_write((PGconn *) BIO_get_app_data(h), buf, size);
BIO_clear_retry_flags(h);
if (res < 0)
{
@@ -1870,6 +1874,15 @@ my_sock_write(BIO *h, const char *buf, int size)
static BIO_METHOD *
my_BIO_s_socket(void)
{
+ BIO_METHOD *res;
+
+#ifdef ENABLE_THREAD_SAFETY
+ if (pthread_mutex_lock(&ssl_config_mutex))
+ return NULL;
+#endif
+
+ res = my_bio_methods;
+
if (!my_bio_methods)
{
BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
@@ -1878,39 +1891,58 @@ my_BIO_s_socket(void)
my_bio_index = BIO_get_new_index();
if (my_bio_index == -1)
- return NULL;
+ goto err;
my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
- my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
- if (!my_bio_methods)
- return NULL;
+ res = BIO_meth_new(my_bio_index, "libpq socket");
+ if (!res)
+ goto err;
/*
* As of this writing, these functions never fail. But check anyway,
* like OpenSSL's own examples do.
*/
- if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
- !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
- !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
- !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
- !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
- !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
- !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
- !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
+ if (!BIO_meth_set_write(res, my_sock_write) ||
+ !BIO_meth_set_read(res, my_sock_read) ||
+ !BIO_meth_set_gets(res, BIO_meth_get_gets(biom)) ||
+ !BIO_meth_set_puts(res, BIO_meth_get_puts(biom)) ||
+ !BIO_meth_set_ctrl(res, BIO_meth_get_ctrl(biom)) ||
+ !BIO_meth_set_create(res, BIO_meth_get_create(biom)) ||
+ !BIO_meth_set_destroy(res, BIO_meth_get_destroy(biom)) ||
+ !BIO_meth_set_callback_ctrl(res, BIO_meth_get_callback_ctrl(biom)))
{
- BIO_meth_free(my_bio_methods);
- my_bio_methods = NULL;
- return NULL;
+ goto err;
}
#else
- my_bio_methods = malloc(sizeof(BIO_METHOD));
- if (!my_bio_methods)
- return NULL;
- memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
- my_bio_methods->bread = my_sock_read;
- my_bio_methods->bwrite = my_sock_write;
+ res = malloc(sizeof(BIO_METHOD));
+ if (!res)
+ goto err;
+ memcpy(res, biom, sizeof(BIO_METHOD));
+ res->bread = my_sock_read;
+ res->bwrite = my_sock_write;
#endif
}
- return my_bio_methods;
+
+ my_bio_methods = res;
+
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
+
+ return res;
+
+err:
+#ifdef HAVE_BIO_METH_NEW
+ if (res)
+ BIO_meth_free(res);
+#else
+ if (res)
+ free(res);
+#endif
+
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+#endif
+ return NULL;
}
/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
@@ -1933,7 +1965,7 @@ my_SSL_set_fd(PGconn *conn, int fd)
SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
goto err;
}
- BIO_set_data(bio, conn);
+ BIO_set_app_data(bio, conn);
SSL_set_bio(conn->ssl, bio, bio);
BIO_set_fd(bio, fd, BIO_NOCLOSE);
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index a1dc7b7..4c85b72 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -235,6 +235,8 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
int result_errno = 0;
char sebuf[PG_STRERROR_R_BUFLEN];
+ SOCK_ERRNO_SET(0);
+
n = recv(conn->sock, ptr, len, 0);
if (n < 0)
@@ -262,6 +264,11 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
"\tbefore or while processing the request.\n"));
break;
+ case 0:
+ /* If errno didn't get set, treat it as regular EOF */
+ n = 0;
+ break;
+
default:
appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not receive data from server: %s\n"),
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index ac9042f..0731855 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -553,8 +553,8 @@ struct pg_conn
int gss_SendLength; /* End of data available in gss_SendBuffer */
int gss_SendNext; /* Next index to send a byte from
* gss_SendBuffer */
- int gss_SendConsumed; /* Number of *unencrypted* bytes consumed
- * for current contents of gss_SendBuffer */
+ int gss_SendConsumed; /* Number of source bytes encrypted but
+ * not yet reported as sent */
char *gss_RecvBuffer; /* Received, encrypted data */
int gss_RecvLength; /* End of data available in gss_RecvBuffer */
char *gss_ResultBuffer; /* Decryption of data in gss_RecvBuffer */
@@ -673,7 +673,8 @@ extern void pqSaveMessageField(PGresult *res, char code,
extern void pqSaveParameterStatus(PGconn *conn, const char *name,
const char *value);
extern int pqRowProcessor(PGconn *conn, const char **errmsgp);
-extern void pqCommandQueueAdvance(PGconn *conn);
+extern void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery,
+ bool gotSync);
extern int PQsendQueryContinue(PGconn *conn, const char *query);
/* === in fe-protocol3.c === */
diff --git a/src/interfaces/libpq/po/ru.po b/src/interfaces/libpq/po/ru.po
index 320d4b4..78affba 100644
--- a/src/interfaces/libpq/po/ru.po
+++ b/src/interfaces/libpq/po/ru.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libpq (PostgreSQL current)\n"
"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
-"POT-Creation-Date: 2023-05-03 05:56+0300\n"
+"POT-Creation-Date: 2024-02-02 18:11+0300\n"
"PO-Revision-Date: 2023-08-30 15:09+0300\n"
"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
@@ -77,11 +77,11 @@ msgstr "не удалось сгенерировать разовый код\n"
#: fe-connect.c:5542 fe-connect.c:5641 fe-connect.c:5897 fe-connect.c:5926
#: fe-connect.c:5998 fe-connect.c:6022 fe-connect.c:6040 fe-connect.c:6141
#: fe-connect.c:6150 fe-connect.c:6508 fe-connect.c:6658 fe-connect.c:6924
-#: fe-exec.c:710 fe-exec.c:976 fe-exec.c:1324 fe-exec.c:3144 fe-exec.c:3328
-#: fe-exec.c:4110 fe-exec.c:4275 fe-gssapi-common.c:111 fe-lobj.c:884
-#: fe-protocol3.c:973 fe-protocol3.c:988 fe-protocol3.c:1021
-#: fe-protocol3.c:1729 fe-protocol3.c:2132 fe-secure-common.c:112
-#: fe-secure-gssapi.c:504 fe-secure-openssl.c:454 fe-secure-openssl.c:1266
+#: fe-exec.c:710 fe-exec.c:978 fe-exec.c:1326 fe-exec.c:3165 fe-exec.c:3357
+#: fe-exec.c:4139 fe-exec.c:4304 fe-gssapi-common.c:111 fe-lobj.c:884
+#: fe-protocol3.c:968 fe-protocol3.c:983 fe-protocol3.c:1016
+#: fe-protocol3.c:1724 fe-protocol3.c:2127 fe-secure-common.c:112
+#: fe-secure-gssapi.c:500 fe-secure-openssl.c:460 fe-secure-openssl.c:1272
msgid "out of memory\n"
msgstr "нехватка памяти\n"
@@ -130,7 +130,7 @@ msgid "malformed SCRAM message (invalid server signature)\n"
msgstr "неправильное сообщение SCRAM (неверная сигнатура сервера)\n"
#: fe-auth-scram.c:935 fe-exec.c:527 fe-protocol3.c:207 fe-protocol3.c:232
-#: fe-protocol3.c:261 fe-protocol3.c:279 fe-protocol3.c:360 fe-protocol3.c:733
+#: fe-protocol3.c:256 fe-protocol3.c:274 fe-protocol3.c:355 fe-protocol3.c:728
msgid "out of memory"
msgstr "нехватка памяти"
@@ -702,12 +702,12 @@ msgstr ""
msgid "password retrieved from file \"%s\"\n"
msgstr "пароль получен из файла \"%s\"\n"
-#: fe-exec.c:466 fe-exec.c:3402
+#: fe-exec.c:466 fe-exec.c:3431
#, c-format
msgid "row number %d is out of range 0..%d"
msgstr "номер записи %d вне диапазона 0..%d"
-#: fe-exec.c:528 fe-protocol3.c:1937
+#: fe-exec.c:528 fe-protocol3.c:1932
#, c-format
msgid "%s"
msgstr "%s"
@@ -716,127 +716,127 @@ msgstr "%s"
msgid "write to server failed\n"
msgstr "ошибка при передаче данных серверу\n"
-#: fe-exec.c:875
+#: fe-exec.c:877
msgid "no error text available\n"
msgstr "текст ошибки отсутствует\n"
-#: fe-exec.c:964
+#: fe-exec.c:966
msgid "NOTICE"
msgstr "ЗАМЕЧАНИЕ"
-#: fe-exec.c:1022
+#: fe-exec.c:1024
msgid "PGresult cannot support more than INT_MAX tuples"
msgstr "PGresult не может вместить больше чем INT_MAX кортежей"
-#: fe-exec.c:1034
+#: fe-exec.c:1036
msgid "size_t overflow"
msgstr "переполнение size_t"
-#: fe-exec.c:1448 fe-exec.c:1519 fe-exec.c:1568
+#: fe-exec.c:1450 fe-exec.c:1521 fe-exec.c:1570
msgid "command string is a null pointer\n"
msgstr "указатель на командную строку нулевой\n"
-#: fe-exec.c:1455 fe-exec.c:2914
+#: fe-exec.c:1457 fe-exec.c:2908
#, c-format
msgid "%s not allowed in pipeline mode\n"
msgstr "%s не допускается в конвейерном режиме\n"
-#: fe-exec.c:1525 fe-exec.c:1574 fe-exec.c:1670
+#: fe-exec.c:1527 fe-exec.c:1576 fe-exec.c:1672
#, c-format
msgid "number of parameters must be between 0 and %d\n"
msgstr "число параметров должно быть от 0 до %d\n"
-#: fe-exec.c:1562 fe-exec.c:1664
+#: fe-exec.c:1564 fe-exec.c:1666
msgid "statement name is a null pointer\n"
msgstr "указатель на имя оператора нулевой\n"
-#: fe-exec.c:1708 fe-exec.c:3255
+#: fe-exec.c:1710 fe-exec.c:3276
msgid "no connection to the server\n"
msgstr "нет соединения с сервером\n"
-#: fe-exec.c:1717 fe-exec.c:3264
+#: fe-exec.c:1719 fe-exec.c:3285
msgid "another command is already in progress\n"
msgstr "уже выполняется другая команда\n"
-#: fe-exec.c:1748
+#: fe-exec.c:1750
msgid "cannot queue commands during COPY\n"
msgstr "во время COPY нельзя добавлять команды в очередь\n"
-#: fe-exec.c:1866
+#: fe-exec.c:1868
msgid "length must be given for binary parameter\n"
msgstr "для двоичного параметра должна быть указана длина\n"
-#: fe-exec.c:2189
+#: fe-exec.c:2183
#, c-format
msgid "unexpected asyncStatus: %d\n"
msgstr "неожиданный asyncStatus: %d\n"
-#: fe-exec.c:2347
+#: fe-exec.c:2341
msgid ""
"synchronous command execution functions are not allowed in pipeline mode\n"
msgstr ""
"функции синхронного выполнения команд не допускаются в конвейерном режиме\n"
-#: fe-exec.c:2364
+#: fe-exec.c:2358
msgid "COPY terminated by new PQexec"
msgstr "операция COPY прервана вызовом PQexec"
-#: fe-exec.c:2381
+#: fe-exec.c:2375
msgid "PQexec not allowed during COPY BOTH\n"
msgstr "вызов PQexec не допускается в процессе COPY BOTH\n"
-#: fe-exec.c:2609 fe-exec.c:2665 fe-exec.c:2734 fe-protocol3.c:1868
+#: fe-exec.c:2603 fe-exec.c:2659 fe-exec.c:2728 fe-protocol3.c:1863
msgid "no COPY in progress\n"
msgstr "операция COPY не выполняется\n"
-#: fe-exec.c:2923
+#: fe-exec.c:2917
msgid "connection in wrong state\n"
msgstr "соединение в неправильном состоянии\n"
-#: fe-exec.c:2967
+#: fe-exec.c:2961
msgid "cannot enter pipeline mode, connection not idle\n"
msgstr "перейти в конвейерный режиме нельзя, соединение не простаивает\n"
-#: fe-exec.c:3004 fe-exec.c:3028
+#: fe-exec.c:2998 fe-exec.c:3022
msgid "cannot exit pipeline mode with uncollected results\n"
msgstr "выйти из конвейерного режима нельзя, не собрав все результаты\n"
-#: fe-exec.c:3009
+#: fe-exec.c:3003
msgid "cannot exit pipeline mode while busy\n"
msgstr "выйти из конвейерного режима в занятом состоянии нельзя\n"
-#: fe-exec.c:3021
+#: fe-exec.c:3015
msgid "cannot exit pipeline mode while in COPY\n"
msgstr "выйти из конвейерного режима во время COPY нельзя\n"
-#: fe-exec.c:3188
+#: fe-exec.c:3209
msgid "cannot send pipeline when not in pipeline mode\n"
msgstr "отправить конвейер, не перейдя в конвейерный режим, нельзя\n"
-#: fe-exec.c:3291
+#: fe-exec.c:3320
msgid "invalid ExecStatusType code"
msgstr "неверный код ExecStatusType"
-#: fe-exec.c:3318
+#: fe-exec.c:3347
msgid "PGresult is not an error result\n"
msgstr "В PGresult не передан результат ошибки\n"
-#: fe-exec.c:3386 fe-exec.c:3409
+#: fe-exec.c:3415 fe-exec.c:3438
#, c-format
msgid "column number %d is out of range 0..%d"
msgstr "номер столбца %d вне диапазона 0..%d"
-#: fe-exec.c:3424
+#: fe-exec.c:3453
#, c-format
msgid "parameter number %d is out of range 0..%d"
msgstr "номер параметра %d вне диапазона 0..%d"
-#: fe-exec.c:3735
+#: fe-exec.c:3764
#, c-format
msgid "could not interpret result from server: %s"
msgstr "не удалось интерпретировать ответ сервера: %s"
-#: fe-exec.c:4001 fe-exec.c:4092
+#: fe-exec.c:4030 fe-exec.c:4121
msgid "incomplete multibyte character\n"
msgstr "неполный многобайтный символ\n"
@@ -896,8 +896,8 @@ msgstr "функция pqPutInt не поддерживает integer разме
msgid "connection not open\n"
msgstr "соединение не открыто\n"
-#: fe-misc.c:755 fe-secure-openssl.c:218 fe-secure-openssl.c:325
-#: fe-secure.c:260 fe-secure.c:423
+#: fe-misc.c:755 fe-secure-openssl.c:218 fe-secure-openssl.c:331
+#: fe-secure.c:262 fe-secure.c:430
#, c-format
msgid ""
"server closed the connection unexpectedly\n"
@@ -926,7 +926,7 @@ msgstr "ошибка в %s(): %s\n"
msgid "message type 0x%02x arrived from server while idle"
msgstr "от сервера во время простоя получено сообщение типа 0x%02x"
-#: fe-protocol3.c:393
+#: fe-protocol3.c:388
msgid ""
"server sent data (\"D\" message) without prior row description (\"T\" "
"message)\n"
@@ -934,125 +934,125 @@ msgstr ""
"сервер отправил данные (сообщение \"D\") без предварительного описания "
"строки (сообщение \"T\")\n"
-#: fe-protocol3.c:436
+#: fe-protocol3.c:431
#, c-format
msgid "unexpected response from server; first received character was \"%c\"\n"
msgstr "неожиданный ответ сервера; первый полученный символ: \"%c\"\n"
-#: fe-protocol3.c:461
+#: fe-protocol3.c:456
#, c-format
msgid "message contents do not agree with length in message type \"%c\"\n"
msgstr "содержимое не соответствует длине в сообщении типа \"%c\"\n"
-#: fe-protocol3.c:481
+#: fe-protocol3.c:476
#, c-format
msgid "lost synchronization with server: got message type \"%c\", length %d\n"
msgstr ""
"потеряна синхронизация с сервером: получено сообщение типа \"%c\", длина %d\n"
-#: fe-protocol3.c:533 fe-protocol3.c:573
+#: fe-protocol3.c:528 fe-protocol3.c:568
msgid "insufficient data in \"T\" message"
msgstr "недостаточно данных в сообщении \"T\""
-#: fe-protocol3.c:644 fe-protocol3.c:850
+#: fe-protocol3.c:639 fe-protocol3.c:845
msgid "out of memory for query result"
msgstr "недостаточно памяти для результата запроса"
-#: fe-protocol3.c:713
+#: fe-protocol3.c:708
msgid "insufficient data in \"t\" message"
msgstr "недостаточно данных в сообщении \"t\""
-#: fe-protocol3.c:772 fe-protocol3.c:804 fe-protocol3.c:822
+#: fe-protocol3.c:767 fe-protocol3.c:799 fe-protocol3.c:817
msgid "insufficient data in \"D\" message"
msgstr "недостаточно данных в сообщении \"D\""
-#: fe-protocol3.c:778
+#: fe-protocol3.c:773
msgid "unexpected field count in \"D\" message"
msgstr "неверное число полей в сообщении \"D\""
-#: fe-protocol3.c:1034
+#: fe-protocol3.c:1029
msgid "no error message available\n"
msgstr "нет сообщения об ошибке\n"
#. translator: %s represents a digit string
-#: fe-protocol3.c:1082 fe-protocol3.c:1101
+#: fe-protocol3.c:1077 fe-protocol3.c:1096
#, c-format
msgid " at character %s"
msgstr " символ %s"
-#: fe-protocol3.c:1114
+#: fe-protocol3.c:1109
#, c-format
msgid "DETAIL: %s\n"
msgstr "ПОДРОБНОСТИ: %s\n"
-#: fe-protocol3.c:1117
+#: fe-protocol3.c:1112
#, c-format
msgid "HINT: %s\n"
msgstr "ПОДСКАЗКА: %s\n"
-#: fe-protocol3.c:1120
+#: fe-protocol3.c:1115
#, c-format
msgid "QUERY: %s\n"
msgstr "ЗАПРОС: %s\n"
-#: fe-protocol3.c:1127
+#: fe-protocol3.c:1122
#, c-format
msgid "CONTEXT: %s\n"
msgstr "КОНТЕКСТ: %s\n"
-#: fe-protocol3.c:1136
+#: fe-protocol3.c:1131
#, c-format
msgid "SCHEMA NAME: %s\n"
msgstr "СХЕМА: %s\n"
-#: fe-protocol3.c:1140
+#: fe-protocol3.c:1135
#, c-format
msgid "TABLE NAME: %s\n"
msgstr "ТАБЛИЦА: %s\n"
-#: fe-protocol3.c:1144
+#: fe-protocol3.c:1139
#, c-format
msgid "COLUMN NAME: %s\n"
msgstr "СТОЛБЕЦ: %s\n"
-#: fe-protocol3.c:1148
+#: fe-protocol3.c:1143
#, c-format
msgid "DATATYPE NAME: %s\n"
msgstr "ТИП ДАННЫХ: %s\n"
-#: fe-protocol3.c:1152
+#: fe-protocol3.c:1147
#, c-format
msgid "CONSTRAINT NAME: %s\n"
msgstr "ОГРАНИЧЕНИЕ: %s\n"
-#: fe-protocol3.c:1164
+#: fe-protocol3.c:1159
msgid "LOCATION: "
msgstr "ПОЛОЖЕНИЕ: "
-#: fe-protocol3.c:1166
+#: fe-protocol3.c:1161
#, c-format
msgid "%s, "
msgstr "%s, "
-#: fe-protocol3.c:1168
+#: fe-protocol3.c:1163
#, c-format
msgid "%s:%s"
msgstr "%s:%s"
-#: fe-protocol3.c:1363
+#: fe-protocol3.c:1358
#, c-format
msgid "LINE %d: "
msgstr "СТРОКА %d: "
-#: fe-protocol3.c:1762
+#: fe-protocol3.c:1757
msgid "PQgetline: not doing text COPY OUT\n"
msgstr "PQgetline можно вызывать только во время COPY OUT с текстом\n"
-#: fe-protocol3.c:2139
+#: fe-protocol3.c:2134
msgid "protocol error: no function result\n"
msgstr "ошибка протокола: нет результата функции\n"
-#: fe-protocol3.c:2151
+#: fe-protocol3.c:2146
#, c-format
msgid "protocol error: id=0x%x\n"
msgstr "ошибка протокола: id=0x%x\n"
@@ -1085,119 +1085,119 @@ msgstr ""
msgid "could not get server's host name from server certificate\n"
msgstr "не удалось получить имя сервера из серверного сертификата\n"
-#: fe-secure-gssapi.c:201
+#: fe-secure-gssapi.c:194
msgid "GSSAPI wrap error"
msgstr "ошибка обёртывания сообщения в GSSAPI"
-#: fe-secure-gssapi.c:209
+#: fe-secure-gssapi.c:202
msgid "outgoing GSSAPI message would not use confidentiality\n"
msgstr "исходящее сообщение GSSAPI не будет защищено\n"
-#: fe-secure-gssapi.c:217
+#: fe-secure-gssapi.c:210
#, c-format
msgid "client tried to send oversize GSSAPI packet (%zu > %zu)\n"
msgstr "клиент попытался передать чрезмерно большой пакет GSSAPI (%zu > %zu)\n"
-#: fe-secure-gssapi.c:354 fe-secure-gssapi.c:598
+#: fe-secure-gssapi.c:350 fe-secure-gssapi.c:594
#, c-format
msgid "oversize GSSAPI packet sent by the server (%zu > %zu)\n"
msgstr "сервер передал чрезмерно большой пакет GSSAPI (%zu > %zu)\n"
-#: fe-secure-gssapi.c:393
+#: fe-secure-gssapi.c:389
msgid "GSSAPI unwrap error"
msgstr "ошибка развёртывания сообщения в GSSAPI"
-#: fe-secure-gssapi.c:403
+#: fe-secure-gssapi.c:399
msgid "incoming GSSAPI message did not use confidentiality\n"
msgstr "входящее сообщение GSSAPI не защищено\n"
-#: fe-secure-gssapi.c:644
+#: fe-secure-gssapi.c:640
msgid "could not initiate GSSAPI security context"
msgstr "не удалось инициализировать контекст безопасности GSSAPI"
-#: fe-secure-gssapi.c:672
+#: fe-secure-gssapi.c:668
msgid "GSSAPI size check error"
msgstr "ошибка проверки размера в GSSAPI"
-#: fe-secure-gssapi.c:683
+#: fe-secure-gssapi.c:679
msgid "GSSAPI context establishment error"
msgstr "ошибка установления контекста в GSSAPI"
-#: fe-secure-openssl.c:223 fe-secure-openssl.c:330 fe-secure-openssl.c:1504
+#: fe-secure-openssl.c:223 fe-secure-openssl.c:336 fe-secure-openssl.c:1512
#, c-format
msgid "SSL SYSCALL error: %s\n"
msgstr "ошибка SSL SYSCALL: %s\n"
-#: fe-secure-openssl.c:230 fe-secure-openssl.c:337 fe-secure-openssl.c:1508
+#: fe-secure-openssl.c:230 fe-secure-openssl.c:343 fe-secure-openssl.c:1516
msgid "SSL SYSCALL error: EOF detected\n"
msgstr "ошибка SSL SYSCALL: конец файла (EOF)\n"
-#: fe-secure-openssl.c:241 fe-secure-openssl.c:348 fe-secure-openssl.c:1517
+#: fe-secure-openssl.c:241 fe-secure-openssl.c:354 fe-secure-openssl.c:1525
#, c-format
msgid "SSL error: %s\n"
msgstr "ошибка SSL: %s\n"
-#: fe-secure-openssl.c:256 fe-secure-openssl.c:363
+#: fe-secure-openssl.c:256 fe-secure-openssl.c:369
msgid "SSL connection has been closed unexpectedly\n"
msgstr "SSL-соединение было неожиданно закрыто\n"
-#: fe-secure-openssl.c:262 fe-secure-openssl.c:369 fe-secure-openssl.c:1567
+#: fe-secure-openssl.c:262 fe-secure-openssl.c:375 fe-secure-openssl.c:1575
#, c-format
msgid "unrecognized SSL error code: %d\n"
msgstr "нераспознанный код ошибки SSL: %d\n"
-#: fe-secure-openssl.c:414
+#: fe-secure-openssl.c:420
msgid "could not determine server certificate signature algorithm\n"
msgstr "не удалось определить алгоритм подписи сертификата сервера\n"
-#: fe-secure-openssl.c:435
+#: fe-secure-openssl.c:441
#, c-format
msgid "could not find digest for NID %s\n"
msgstr "не удалось найти алгоритм хеширования по NID %s\n"
-#: fe-secure-openssl.c:445
+#: fe-secure-openssl.c:451
msgid "could not generate peer certificate hash\n"
msgstr "не удалось сгенерировать хеш сертификата сервера\n"
-#: fe-secure-openssl.c:502
+#: fe-secure-openssl.c:508
msgid "SSL certificate's name entry is missing\n"
msgstr "в SSL-сертификате отсутствует запись имени\n"
-#: fe-secure-openssl.c:537
+#: fe-secure-openssl.c:543
msgid "SSL certificate's address entry is missing\n"
msgstr "в SSL-сертификате отсутствует запись адреса\n"
-#: fe-secure-openssl.c:955
+#: fe-secure-openssl.c:961
#, c-format
msgid "could not create SSL context: %s\n"
msgstr "не удалось создать контекст SSL: %s\n"
-#: fe-secure-openssl.c:994
+#: fe-secure-openssl.c:1000
#, c-format
msgid "invalid value \"%s\" for minimum SSL protocol version\n"
msgstr "неверное значение \"%s\" для минимальной версии протокола SSL\n"
-#: fe-secure-openssl.c:1005
+#: fe-secure-openssl.c:1011
#, c-format
msgid "could not set minimum SSL protocol version: %s\n"
msgstr "не удалось задать минимальную версию протокола SSL: %s\n"
-#: fe-secure-openssl.c:1023
+#: fe-secure-openssl.c:1029
#, c-format
msgid "invalid value \"%s\" for maximum SSL protocol version\n"
msgstr "неверное значение \"%s\" для максимальной версии протокола SSL\n"
-#: fe-secure-openssl.c:1034
+#: fe-secure-openssl.c:1040
#, c-format
msgid "could not set maximum SSL protocol version: %s\n"
msgstr "не удалось задать максимальную версию протокола SSL: %s\n"
-#: fe-secure-openssl.c:1070
+#: fe-secure-openssl.c:1076
#, c-format
msgid "could not read root certificate file \"%s\": %s\n"
msgstr "не удалось прочитать файл корневых сертификатов \"%s\": %s\n"
-#: fe-secure-openssl.c:1123
+#: fe-secure-openssl.c:1129
msgid ""
"could not get home directory to locate root certificate file\n"
"Either provide the file or change sslmode to disable server certificate "
@@ -1207,7 +1207,7 @@ msgstr ""
"Укажите полный путь к файлу или отключите проверку сертификата сервера, "
"изменив sslmode.\n"
-#: fe-secure-openssl.c:1127
+#: fe-secure-openssl.c:1133
#, c-format
msgid ""
"root certificate file \"%s\" does not exist\n"
@@ -1218,63 +1218,63 @@ msgstr ""
"Укажите полный путь к файлу или отключите проверку сертификата сервера, "
"изменив sslmode.\n"
-#: fe-secure-openssl.c:1158
+#: fe-secure-openssl.c:1164
#, c-format
msgid "could not open certificate file \"%s\": %s\n"
msgstr "не удалось открыть файл сертификата \"%s\": %s\n"
-#: fe-secure-openssl.c:1177
+#: fe-secure-openssl.c:1183
#, c-format
msgid "could not read certificate file \"%s\": %s\n"
msgstr "не удалось прочитать файл сертификата \"%s\": %s\n"
-#: fe-secure-openssl.c:1202
+#: fe-secure-openssl.c:1208
#, c-format
msgid "could not establish SSL connection: %s\n"
msgstr "не удалось установить SSL-соединение: %s\n"
-#: fe-secure-openssl.c:1236
+#: fe-secure-openssl.c:1242
#, c-format
msgid "could not set SSL Server Name Indication (SNI): %s\n"
msgstr ""
"не удалось задать SNI (Server Name Indication) для SSL-подключения: %s\n"
-#: fe-secure-openssl.c:1282
+#: fe-secure-openssl.c:1288
#, c-format
msgid "could not load SSL engine \"%s\": %s\n"
msgstr "не удалось загрузить модуль SSL ENGINE \"%s\": %s\n"
-#: fe-secure-openssl.c:1294
+#: fe-secure-openssl.c:1300
#, c-format
msgid "could not initialize SSL engine \"%s\": %s\n"
msgstr "не удалось инициализировать модуль SSL ENGINE \"%s\": %s\n"
-#: fe-secure-openssl.c:1310
+#: fe-secure-openssl.c:1316
#, c-format
msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n"
msgstr "не удалось прочитать закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n"
-#: fe-secure-openssl.c:1324
+#: fe-secure-openssl.c:1330
#, c-format
msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n"
msgstr "не удалось загрузить закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n"
-#: fe-secure-openssl.c:1362
+#: fe-secure-openssl.c:1368
#, c-format
msgid "certificate present, but not private key file \"%s\"\n"
msgstr "при наличии сертификата отсутствует файл закрытого ключа \"%s\"\n"
-#: fe-secure-openssl.c:1366
+#: fe-secure-openssl.c:1372
#, c-format
msgid "could not stat private key file \"%s\": %m\n"
msgstr "не удалось получить информацию о файле закрытого ключа \"%s\": %m\n"
-#: fe-secure-openssl.c:1375
+#: fe-secure-openssl.c:1381
#, c-format
msgid "private key file \"%s\" is not a regular file\n"
msgstr "файл закрытого ключа \"%s\" - не обычный файл\n"
-#: fe-secure-openssl.c:1408
+#: fe-secure-openssl.c:1414
#, c-format
msgid ""
"private key file \"%s\" has group or world access; file must have "
@@ -1286,17 +1286,17 @@ msgstr ""
"текущему пользователю, либо u=rw,g=r (0640) или более строгие, если он "
"принадлежит root\n"
-#: fe-secure-openssl.c:1433
+#: fe-secure-openssl.c:1439
#, c-format
msgid "could not load private key file \"%s\": %s\n"
msgstr "не удалось загрузить файл закрытого ключа \"%s\": %s\n"
-#: fe-secure-openssl.c:1450
+#: fe-secure-openssl.c:1456
#, c-format
msgid "certificate does not match private key file \"%s\": %s\n"
msgstr "сертификат не соответствует файлу закрытого ключа \"%s\": %s\n"
-#: fe-secure-openssl.c:1550
+#: fe-secure-openssl.c:1558
#, c-format
msgid ""
"This may indicate that the server does not support any SSL protocol version "
@@ -1305,32 +1305,32 @@ msgstr ""
"Это может указывать на то, что сервер не поддерживает ни одну версию "
"протокола SSL между %s и %s.\n"
-#: fe-secure-openssl.c:1586
+#: fe-secure-openssl.c:1594
#, c-format
msgid "certificate could not be obtained: %s\n"
msgstr "не удалось получить сертификат: %s\n"
-#: fe-secure-openssl.c:1692
+#: fe-secure-openssl.c:1700
#, c-format
msgid "no SSL error reported"
msgstr "нет сообщения об ошибке SSL"
-#: fe-secure-openssl.c:1701
+#: fe-secure-openssl.c:1709
#, c-format
msgid "SSL error code %lu"
msgstr "код ошибки SSL: %lu"
-#: fe-secure-openssl.c:1956
+#: fe-secure-openssl.c:1988
#, c-format
msgid "WARNING: sslpassword truncated\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: значение sslpassword усечено\n"
-#: fe-secure.c:267
+#: fe-secure.c:274
#, c-format
msgid "could not receive data from server: %s\n"
msgstr "не удалось получить данные с сервера: %s\n"
-#: fe-secure.c:436
+#: fe-secure.c:443
#, c-format
msgid "could not send data to server: %s\n"
msgstr "не удалось передать данные серверу: %s\n"