fix-typo-comparison-variables.patch
application/octet-stream
Filename: fix-typo-comparison-variables.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/reindexdb.sgml | 2 | 1 |
| src/backend/access/transam/slru.c | 1 | 1 |
| src/backend/access/transam/transam.c | 40 | 81 |
| src/backend/commands/cluster.c | 1 | 1 |
| src/backend/commands/explain.c | 3 | 3 |
| src/backend/lib/dshash.c | 112 | 149 |
| src/backend/libpq/be-secure-openssl.c | 103 | 95 |
| src/backend/nodes/bitmapset.c | 9 | 21 |
| src/backend/optimizer/path/clausesel.c | 6 | 0 |
| src/backend/optimizer/path/indxpath.c | 4 | 3 |
| src/backend/optimizer/util/joininfo.c | 2 | 24 |
| src/backend/utils/adt/amutils.c | 3 | 3 |
| src/backend/utils/error/elog.c | 17 | 0 |
| src/bin/pg_ctl/pg_ctl.c | 4 | 4 |
| src/bin/psql/variables.c | 1 | 1 |
| src/bin/scripts/common.c | 3 | 3 |
| src/bin/scripts/createuser.c | 1 | 1 |
| src/bin/scripts/reindexdb.c | 10 | 12 |
| src/bin/scripts/vacuumdb.c | 5 | 11 |
| src/common/username.c | 5 | 2 |
| src/include/lib/simplehash.h | 14 | 14 |
| src/include/port/pg_bitutils.h | 2 | 2 |
| src/include/storage/read_stream.h | 64 | 0 |
| src/interfaces/libpq/fe-misc.c | 2 | 2 |
| src/interfaces/libpq/fe-secure-openssl.c | 160 | 152 |
| src/port/pg_bitutils.c | 9 | 9 |
| src/port/snprintf.c | 4 | 4 |
| src/port/win32setlocale.c | 3 | 3 |
| src/test/modules/test_escape/test_escape.c | 4 | 2 |
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
index 98c3333228..a877439dc5 100644
--- a/doc/src/sgml/ref/reindexdb.sgml
+++ b/doc/src/sgml/ref/reindexdb.sgml
@@ -179,7 +179,8 @@ PostgreSQL documentation
setting is high enough to accommodate all connections.
</para>
<para>
- Note that this option is incompatible with the <option>--system</option> option.
+ Note that this option is incompatible with the <option>--index</option>
+ and <option>--system</option> options.
</para>
</listitem>
</varlistentry>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 9ce628e62a..2ee7679cce 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -1353,7 +1353,7 @@ SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
}
/* Do nothing if slot is unused */
- if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
+ if (shared->page_status[slotno] != SLRU_PAGE_VALID)
continue;
SlruInternalWritePage(ctl, slotno, &fdata);
diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c
index 9a39451a29..14dc9b116c 100644
--- a/src/backend/access/transam/transam.c
+++ b/src/backend/access/transam/transam.c
@@ -125,50 +125,26 @@ TransactionLogFetch(TransactionId transactionId)
bool /* true if given transaction committed */
TransactionIdDidCommit(TransactionId transactionId)
{
- XidStatus xidstatus;
-
- xidstatus = TransactionLogFetch(transactionId);
-
- /*
- * If it's marked committed, it's committed.
- */
- if (xidstatus == TRANSACTION_STATUS_COMMITTED)
- return true;
-
- /*
- * If it's marked subcommitted, we have to check the parent recursively.
- * However, if it's older than TransactionXmin, we can't look at
- * pg_subtrans; instead assume that the parent crashed without cleaning up
- * its children.
- *
- * Originally we Assert'ed that the result of SubTransGetParent was not
- * zero. However with the introduction of prepared transactions, there can
- * be a window just after database startup where we do not have complete
- * knowledge in pg_subtrans of the transactions after TransactionXmin.
- * StartupSUBTRANS() has ensured that any missing information will be
- * zeroed. Since this case should not happen under normal conditions, it
- * seems reasonable to emit a WARNING for it.
- */
- if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
- {
- TransactionId parentXid;
-
- if (TransactionIdPrecedes(transactionId, TransactionXmin))
- return false;
- parentXid = SubTransGetParent(transactionId);
- if (!TransactionIdIsValid(parentXid))
- {
- elog(WARNING, "no pg_subtrans entry for subcommitted XID %u",
- transactionId);
- return false;
- }
- return TransactionIdDidCommit(parentXid);
- }
-
- /*
- * It's not committed.
- */
- return false;
+ XidStatus xidstatus;
+
+ while (true) {
+ xidstatus = TransactionLogFetch(transactionId);
+
+ if (xidstatus == TRANSACTION_STATUS_COMMITTED)
+ return true;
+
+ if (xidstatus != TRANSACTION_STATUS_SUB_COMMITTED)
+ return false;
+
+ if (unlikely(TransactionIdPrecedes(transactionId, TransactionXmin)))
+ return false;
+
+ transactionId = SubTransGetParent(transactionId);
+ if (unlikely(!TransactionIdIsValid(transactionId))) {
+ elog(WARNING, "no pg_subtrans entry for subcommitted XID %u", transactionId);
+ return false;
+ }
+ }
}
/*
@@ -187,43 +163,26 @@ TransactionIdDidCommit(TransactionId transactionId)
bool /* true if given transaction aborted */
TransactionIdDidAbort(TransactionId transactionId)
{
- XidStatus xidstatus;
-
- xidstatus = TransactionLogFetch(transactionId);
-
- /*
- * If it's marked aborted, it's aborted.
- */
- if (xidstatus == TRANSACTION_STATUS_ABORTED)
- return true;
-
- /*
- * If it's marked subcommitted, we have to check the parent recursively.
- * However, if it's older than TransactionXmin, we can't look at
- * pg_subtrans; instead assume that the parent crashed without cleaning up
- * its children.
- */
- if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
- {
- TransactionId parentXid;
-
- if (TransactionIdPrecedes(transactionId, TransactionXmin))
- return true;
- parentXid = SubTransGetParent(transactionId);
- if (!TransactionIdIsValid(parentXid))
- {
- /* see notes in TransactionIdDidCommit */
- elog(WARNING, "no pg_subtrans entry for subcommitted XID %u",
- transactionId);
- return true;
- }
- return TransactionIdDidAbort(parentXid);
- }
-
- /*
- * It's not aborted.
- */
- return false;
+ XidStatus xidstatus;
+
+ while (true) {
+ xidstatus = TransactionLogFetch(transactionId);
+
+ if (xidstatus == TRANSACTION_STATUS_ABORTED)
+ return true;
+
+ if (xidstatus != TRANSACTION_STATUS_SUB_COMMITTED)
+ return false;
+
+ if (unlikely(TransactionIdPrecedes(transactionId, TransactionXmin)))
+ return true;
+
+ transactionId = SubTransGetParent(transactionId);
+ if (unlikely(!TransactionIdIsValid(transactionId))) {
+ elog(WARNING, "no pg_subtrans entry for subcommitted XID %u", transactionId);
+ return true;
+ }
+ }
}
/*
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 54a08e4102..17f2e0665a 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -949,7 +949,7 @@ copy_table_data(Relation NewHeap, Relation OldHeap, Relation OldIndex, bool verb
* tells us it's cheaper. Otherwise, always indexscan if an index is
* provided, else plain seqscan.
*/
- if (OldIndex != NULL && OldIndex->rd_rel->relam == BTREE_AM_OID)
+ if (OldIndex != NULL)
use_sort = plan_cluster_use_sort(RelationGetRelid(OldHeap),
RelationGetRelid(OldIndex));
else
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 391b34a2af..5803b404a6 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -738,14 +738,14 @@ ExplainPrintSettings(ExplainState *es)
for (int i = 0; i < num; i++)
{
- char *setting;
struct config_generic *conf = gucs[i];
+ char *setting;
+
+ setting = GetConfigOptionByName(conf->name, NULL, true);
if (i > 0)
appendStringInfoString(&str, ", ");
- setting = GetConfigOptionByName(conf->name, NULL, true);
-
if (setting)
appendStringInfo(&str, "%s = '%s'", conf->name, setting);
else
diff --git a/src/backend/lib/dshash.c b/src/backend/lib/dshash.c
index b8d031f201..3a70c8d6ee 100644
--- a/src/backend/lib/dshash.c
+++ b/src/backend/lib/dshash.c
@@ -74,6 +74,7 @@ typedef struct dshash_partition
{
LWLock lock; /* Protects all buckets in this partition. */
size_t count; /* # of items in this partition's buckets */
+ char padding[PG_CACHE_LINE_SIZE - sizeof(LWLock) - sizeof(size_t)];
} dshash_partition;
/*
@@ -656,86 +657,58 @@ dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table,
void *
dshash_seq_next(dshash_seq_status *status)
{
- dsa_pointer next_item_pointer;
-
- /*
- * Not yet holding any partition locks. Need to determine the size of the
- * hash table, it could have been resized since we were looking last.
- * Since we iterate in partition order, we can start by unconditionally
- * lock partition 0.
- *
- * Once we hold the lock, no resizing can happen until the scan ends. So
- * we don't need to repeatedly call ensure_valid_bucket_pointers().
- */
- if (status->curpartition == -1)
- {
- Assert(status->curbucket == 0);
- ASSERT_NO_PARTITION_LOCKS_HELD_BY_ME(status->hash_table);
-
- status->curpartition = 0;
-
- LWLockAcquire(PARTITION_LOCK(status->hash_table,
- status->curpartition),
- status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
-
- ensure_valid_bucket_pointers(status->hash_table);
-
- status->nbuckets =
- NUM_BUCKETS(status->hash_table->control->size_log2);
- next_item_pointer = status->hash_table->buckets[status->curbucket];
- }
- else
- next_item_pointer = status->pnextitem;
-
- Assert(LWLockHeldByMeInMode(PARTITION_LOCK(status->hash_table,
- status->curpartition),
- status->exclusive ? LW_EXCLUSIVE : LW_SHARED));
-
- /* Move to the next bucket if we finished the current bucket */
- while (!DsaPointerIsValid(next_item_pointer))
- {
- int next_partition;
-
- if (++status->curbucket >= status->nbuckets)
- {
- /* all buckets have been scanned. finish. */
- return NULL;
- }
-
- /* Check if move to the next partition */
- next_partition =
- PARTITION_FOR_BUCKET_INDEX(status->curbucket,
- status->hash_table->size_log2);
-
- if (status->curpartition != next_partition)
- {
- /*
- * Move to the next partition. Lock the next partition then
- * release the current, not in the reverse order to avoid
- * concurrent resizing. Avoid dead lock by taking lock in the
- * same order with resize().
- */
- LWLockAcquire(PARTITION_LOCK(status->hash_table,
- next_partition),
- status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
- LWLockRelease(PARTITION_LOCK(status->hash_table,
- status->curpartition));
- status->curpartition = next_partition;
- }
-
- next_item_pointer = status->hash_table->buckets[status->curbucket];
- }
-
- status->curitem =
- dsa_get_address(status->hash_table->area, next_item_pointer);
-
- /*
- * The caller may delete the item. Store the next item in case of
- * deletion.
- */
- status->pnextitem = status->curitem->next;
-
- return ENTRY_FROM_ITEM(status->curitem);
+ dsa_pointer next_item_pointer;
+
+ if (status->curpartition == -1)
+ {
+ /* Initialize the scan. */
+ status->curpartition = 0;
+ LWLockAcquire(PARTITION_LOCK(status->hash_table,
+ status->curpartition),
+ status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
+ ensure_valid_bucket_pointers(status->hash_table);
+ status->nbuckets =
+ NUM_BUCKETS(status->hash_table->control->size_log2);
+ next_item_pointer = status->hash_table->buckets[status->curbucket];
+ }
+ else
+ next_item_pointer = status->pnextitem;
+
+ while (true)
+ {
+ /* Process the current bucket. */
+ while (DsaPointerIsValid(next_item_pointer))
+ {
+ status->curitem =
+ dsa_get_address(status->hash_table->area, next_item_pointer);
+ status->pnextitem = status->curitem->next;
+ return ENTRY_FROM_ITEM(status->curitem);
+ }
+
+ /* Move to the next bucket. */
+ if (++status->curbucket >= status->nbuckets)
+ {
+ /* All buckets have been scanned. */
+ return NULL;
+ }
+
+ /* Check if we need to switch partitions. */
+ int next_partition =
+ PARTITION_FOR_BUCKET_INDEX(status->curbucket,
+ status->hash_table->size_log2);
+
+ if (status->curpartition != next_partition)
+ {
+ LWLockAcquire(PARTITION_LOCK(status->hash_table,
+ next_partition),
+ status->exclusive ? LW_EXCLUSIVE : LW_SHARED);
+ LWLockRelease(PARTITION_LOCK(status->hash_table,
+ status->curpartition));
+ status->curpartition = next_partition;
+ }
+
+ next_item_pointer = status->hash_table->buckets[status->curbucket];
+ }
}
/*
@@ -857,75 +830,65 @@ delete_item(dshash_table *hash_table, dshash_table_item *item)
static void
resize(dshash_table *hash_table, size_t new_size_log2)
{
- dsa_pointer old_buckets;
- dsa_pointer new_buckets_shared;
- dsa_pointer *new_buckets;
- size_t size;
- size_t new_size = ((size_t) 1) << new_size_log2;
- size_t i;
-
- /*
- * Acquire the locks for all lock partitions. This is expensive, but we
- * shouldn't have to do it many times.
- */
- for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
- {
- Assert(!LWLockHeldByMe(PARTITION_LOCK(hash_table, i)));
-
- LWLockAcquire(PARTITION_LOCK(hash_table, i), LW_EXCLUSIVE);
- if (i == 0 && hash_table->control->size_log2 >= new_size_log2)
- {
- /*
- * Another backend has already increased the size; we can avoid
- * obtaining all the locks and return early.
- */
- LWLockRelease(PARTITION_LOCK(hash_table, 0));
- return;
- }
- }
-
- Assert(new_size_log2 == hash_table->control->size_log2 + 1);
-
- /* Allocate the space for the new table. */
- new_buckets_shared =
- dsa_allocate_extended(hash_table->area,
- sizeof(dsa_pointer) * new_size,
- DSA_ALLOC_HUGE | DSA_ALLOC_ZERO);
- new_buckets = dsa_get_address(hash_table->area, new_buckets_shared);
-
- /*
- * We've allocated the new bucket array; all that remains to do now is to
- * reinsert all items, which amounts to adjusting all the pointers.
- */
- size = ((size_t) 1) << hash_table->control->size_log2;
- for (i = 0; i < size; ++i)
- {
- dsa_pointer item_pointer = hash_table->buckets[i];
-
- while (DsaPointerIsValid(item_pointer))
- {
- dshash_table_item *item;
- dsa_pointer next_item_pointer;
-
- item = dsa_get_address(hash_table->area, item_pointer);
- next_item_pointer = item->next;
- insert_item_into_bucket(hash_table, item_pointer, item,
- &new_buckets[BUCKET_INDEX_FOR_HASH_AND_SIZE(item->hash,
- new_size_log2)]);
- item_pointer = next_item_pointer;
- }
- }
-
- /* Swap the hash table into place and free the old one. */
- old_buckets = hash_table->control->buckets;
- hash_table->control->buckets = new_buckets_shared;
- hash_table->control->size_log2 = new_size_log2;
- hash_table->buckets = new_buckets;
- dsa_free(hash_table->area, old_buckets);
-
- /* Release all the locks. */
- for (i = 0; i < DSHASH_NUM_PARTITIONS; ++i)
- LWLockRelease(PARTITION_LOCK(hash_table, i));
+ dsa_pointer old_buckets;
+ dsa_pointer new_buckets_shared;
+ dsa_pointer *new_buckets;
+ size_t size;
+ size_t new_size = ((size_t) 1) << new_size_log2;
+ size_t i;
+
+ /* Allocate and initialize the new bucket array without locks. */
+ new_buckets_shared =
+ dsa_allocate_extended(hash_table->area,
+ sizeof(dsa_pointer) * new_size,
+ DSA_ALLOC_HUGE | DSA_ALLOC_ZERO);
+ new_buckets = dsa_get_address(hash_table->area, new_buckets_shared);
+
+ /* Acquire locks and update pointers. */
+ for (i = 0; i < DSHASH_NUM_PARTITIONS; i++)
+ LWLockAcquire(PARTITION_LOCK(hash_table, i), LW_EXCLUSIVE);
+
+ /* Check if another backend has already resized the table. */
+ if (hash_table->control->size_log2 >= new_size_log2)
+ {
+ dsa_free(hash_table->area, new_buckets_shared);
+
+ for (i = 0; i < DSHASH_NUM_PARTITIONS; i++)
+ LWLockRelease(PARTITION_LOCK(hash_table, i));
+
+ return;
+ }
+
+ /* Reinsert all items into the new bucket array. */
+ size = ((size_t) 1) << hash_table->control->size_log2;
+ for (i = 0; i < size; i++)
+ {
+ dsa_pointer item_pointer = hash_table->buckets[i];
+
+ while (DsaPointerIsValid(item_pointer))
+ {
+ dshash_table_item *item;
+ dsa_pointer next_item_pointer;
+
+ item = dsa_get_address(hash_table->area, item_pointer);
+ next_item_pointer = item->next;
+ insert_item_into_bucket(hash_table, item_pointer, item,
+ &new_buckets[BUCKET_INDEX_FOR_HASH_AND_SIZE(item->hash,
+ new_size_log2)]);
+ item_pointer = next_item_pointer;
+ }
+ }
+
+ /* Swap the hash table into place and free the old one. */
+ old_buckets = hash_table->control->buckets;
+ hash_table->control->buckets = new_buckets_shared;
+ hash_table->control->size_log2 = new_size_log2;
+ hash_table->buckets = new_buckets;
+ dsa_free(hash_table->area, old_buckets);
+
+ /* Release all the locks. */
+ for (i = 0; i < DSHASH_NUM_PARTITIONS; i++)
+ LWLockRelease(PARTITION_LOCK(hash_table, i));
}
/*
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 64ff3ce3d6..947636816a 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -765,56 +765,60 @@ ssize_t
be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
{
ssize_t n;
- int err;
- unsigned long ecode;
errno = 0;
ERR_clear_error();
n = SSL_read(port->ssl, ptr, len);
- err = SSL_get_error(port->ssl, n);
- ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
- switch (err)
+ if (n <= 0)
{
- case SSL_ERROR_NONE:
- /* a-ok */
- break;
- case SSL_ERROR_WANT_READ:
- *waitfor = WL_SOCKET_READABLE;
- errno = EWOULDBLOCK;
- n = -1;
- break;
- case SSL_ERROR_WANT_WRITE:
- *waitfor = WL_SOCKET_WRITEABLE;
- errno = EWOULDBLOCK;
- n = -1;
- break;
- case SSL_ERROR_SYSCALL:
- /* leave it to caller to ereport the value of errno */
- if (n != -1 || errno == 0)
- {
+ int err;
+ unsigned long ecode;
+
+ err = SSL_get_error(port->ssl, n);
+ ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
+ switch (err)
+ {
+ case SSL_ERROR_NONE:
+ /* a-ok */
+ break;
+ case SSL_ERROR_WANT_READ:
+ *waitfor = WL_SOCKET_READABLE;
+ errno = EWOULDBLOCK;
+ n = -1;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ *waitfor = WL_SOCKET_WRITEABLE;
+ errno = EWOULDBLOCK;
+ n = -1;
+ break;
+ case SSL_ERROR_SYSCALL:
+ /* leave it to caller to ereport the value of errno */
+ if (n != -1 || errno == 0)
+ {
+ errno = ECONNRESET;
+ n = -1;
+ }
+ break;
+ case SSL_ERROR_SSL:
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("SSL error: %s", SSLerrmessage(ecode))));
errno = ECONNRESET;
n = -1;
- }
- break;
- case SSL_ERROR_SSL:
- ereport(COMMERROR,
- (errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("SSL error: %s", SSLerrmessage(ecode))));
- errno = ECONNRESET;
- n = -1;
- break;
- case SSL_ERROR_ZERO_RETURN:
- /* connection was cleanly shut down by peer */
- n = 0;
- break;
- default:
- ereport(COMMERROR,
- (errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("unrecognized SSL error code: %d",
- err)));
- errno = ECONNRESET;
- n = -1;
- break;
+ break;
+ case SSL_ERROR_ZERO_RETURN:
+ /* connection was cleanly shut down by peer */
+ n = 0;
+ break;
+ default:
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("unrecognized SSL error code: %d",
+ err)));
+ errno = ECONNRESET;
+ n = -1;
+ break;
+ }
}
return n;
@@ -824,67 +828,71 @@ ssize_t
be_tls_write(Port *port, const void *ptr, size_t len, int *waitfor)
{
ssize_t n;
- int err;
- unsigned long ecode;
errno = 0;
ERR_clear_error();
n = SSL_write(port->ssl, ptr, len);
- err = SSL_get_error(port->ssl, n);
- ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
- switch (err)
+ if (n <= 0)
{
- case SSL_ERROR_NONE:
- /* a-ok */
- break;
- case SSL_ERROR_WANT_READ:
- *waitfor = WL_SOCKET_READABLE;
- errno = EWOULDBLOCK;
- n = -1;
- break;
- case SSL_ERROR_WANT_WRITE:
- *waitfor = WL_SOCKET_WRITEABLE;
- errno = EWOULDBLOCK;
- n = -1;
- break;
- case SSL_ERROR_SYSCALL:
+ int err;
+ unsigned long ecode;
- /*
- * Leave it to caller to ereport the value of errno. However, if
- * errno is still zero then assume it's a read EOF situation, and
- * report ECONNRESET. (This seems possible because SSL_write can
- * also do reads.)
- */
- if (n != -1 || errno == 0)
- {
+ err = SSL_get_error(port->ssl, n);
+ ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
+ switch (err)
+ {
+ case SSL_ERROR_NONE:
+ /* a-ok */
+ break;
+ case SSL_ERROR_WANT_READ:
+ *waitfor = WL_SOCKET_READABLE;
+ errno = EWOULDBLOCK;
+ n = -1;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ *waitfor = WL_SOCKET_WRITEABLE;
+ errno = EWOULDBLOCK;
+ n = -1;
+ break;
+ case SSL_ERROR_SYSCALL:
+
+ /*
+ * Leave it to caller to ereport the value of errno. However, if
+ * errno is still zero then assume it's a read EOF situation, and
+ * report ECONNRESET. (This seems possible because SSL_write can
+ * also do reads.)
+ */
+ if (n != -1 || errno == 0)
+ {
+ errno = ECONNRESET;
+ n = -1;
+ }
+ break;
+ case SSL_ERROR_SSL:
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("SSL error: %s", SSLerrmessage(ecode))));
errno = ECONNRESET;
n = -1;
- }
- break;
- case SSL_ERROR_SSL:
- ereport(COMMERROR,
- (errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("SSL error: %s", SSLerrmessage(ecode))));
- errno = ECONNRESET;
- n = -1;
- break;
- case SSL_ERROR_ZERO_RETURN:
+ break;
+ case SSL_ERROR_ZERO_RETURN:
- /*
- * the SSL connection was closed, leave it to the caller to
- * ereport it
- */
- errno = ECONNRESET;
- n = -1;
- break;
- default:
- ereport(COMMERROR,
- (errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("unrecognized SSL error code: %d",
- err)));
- errno = ECONNRESET;
- n = -1;
- break;
+ /*
+ * the SSL connection was closed, leave it to the caller to
+ * ereport it
+ */
+ errno = ECONNRESET;
+ n = -1;
+ break;
+ default:
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("unrecognized SSL error code: %d",
+ err)));
+ errno = ECONNRESET;
+ n = -1;
+ break;
+ }
}
return n;
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index bf512cf806..d65c2ea429 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -831,16 +831,13 @@ bms_add_member(Bitmapset *a, int x)
if (wordnum >= a->nwords)
{
int oldnwords = a->nwords;
- int i;
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(wordnum + 1));
- a->nwords = wordnum + 1;
+
/* zero out the enlarged portion */
- i = oldnwords;
- do
- {
- a->words[i] = 0;
- } while (++i < a->nwords);
+ memset(&a->words[oldnwords], 0, (wordnum + 1 - oldnwords) * sizeof(bitmapword));
+
+ a->nwords = wordnum + 1;
}
a->words[wordnum] |= ((bitmapword) 1 << bitnum);
@@ -971,8 +968,6 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
Bitmapset *
bms_replace_members(Bitmapset *a, const Bitmapset *b)
{
- int i;
-
Assert(bms_is_valid_set(a));
Assert(bms_is_valid_set(b));
@@ -987,11 +982,7 @@ bms_replace_members(Bitmapset *a, const Bitmapset *b)
if (a->nwords < b->nwords)
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(b->nwords));
- i = 0;
- do
- {
- a->words[i] = b->words[i];
- } while (++i < b->nwords);
+ memcpy(a->words, b->words, b->nwords * sizeof(bitmapword));
a->nwords = b->nwords;
@@ -1049,17 +1040,14 @@ bms_add_range(Bitmapset *a, int lower, int upper)
else if (uwordnum >= a->nwords)
{
int oldnwords = a->nwords;
- int i;
/* ensure we have enough words to store the upper bit */
a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1));
- a->nwords = uwordnum + 1;
+
/* zero out the enlarged portion */
- i = oldnwords;
- do
- {
- a->words[i] = 0;
- } while (++i < a->nwords);
+ memset(&a->words[oldnwords], 0, (uwordnum + 1 - oldnwords) * sizeof(bitmapword));
+
+ a->nwords = uwordnum + 1;
}
wordnum = lwordnum = WORDNUM(lower);
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 5d51f97f21..a4882081ae 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -128,6 +128,9 @@ clauselist_selectivity_ext(PlannerInfo *root,
ListCell *l;
int listidx;
+ if (clauses == NIL)
+ return s1;
+
/*
* If there's exactly one clause, just go directly to
* clause_selectivity_ext(). None of what we might do below is relevant.
@@ -525,6 +528,9 @@ find_single_rel_for_clauses(PlannerInfo *root, List *clauses)
int lastrelid = 0;
ListCell *l;
+ if (clauses == NIL)
+ return NULL;
+
foreach(l, clauses)
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index a43ca16d68..c983753f84 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -4286,7 +4286,8 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
{
matched = true; /* column is unique */
- if (bms_membership(rinfo->clause_relids) == BMS_SINGLETON)
+ if (extra_clauses &&
+ bms_membership(rinfo->clause_relids) == BMS_SINGLETON)
{
MemoryContext oldMemCtx =
MemoryContextSwitchTo(root->planner_cxt);
@@ -4298,8 +4299,8 @@ relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel,
*/
Assert(bms_is_empty(rinfo->left_relids) ||
bms_is_empty(rinfo->right_relids));
- if (extra_clauses)
- exprs = lappend(exprs, rinfo);
+
+ exprs = lappend(exprs, rinfo);
MemoryContextSwitchTo(oldMemCtx);
}
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index f26e38c655..a3fe316d8a 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -106,33 +106,11 @@ add_join_clause_to_rels(PlannerInfo *root,
return;
/*
- * Substitute the origin qual with constant-FALSE if it is provably always
+ * Substitute the origin qual with constant-FALSE if it is probably always
* false.
- *
- * Note that we need to keep the same rinfo_serial, since it is in
- * practice the same condition. We also need to reset the
- * last_rinfo_serial counter, which is essential to ensure that the
- * RestrictInfos for the "same" qual condition get identical serial
- * numbers (see deconstruct_distribute_oj_quals).
*/
if (restriction_is_always_false(root, restrictinfo))
- {
- int save_rinfo_serial = restrictinfo->rinfo_serial;
- int save_last_rinfo_serial = root->last_rinfo_serial;
-
- restrictinfo = make_restrictinfo(root,
- (Expr *) makeBoolConst(false, false),
- restrictinfo->is_pushed_down,
- restrictinfo->has_clone,
- restrictinfo->is_clone,
- restrictinfo->pseudoconstant,
- 0, /* security_level */
- restrictinfo->required_relids,
- restrictinfo->incompatible_relids,
- restrictinfo->outer_relids);
- restrictinfo->rinfo_serial = save_rinfo_serial;
- root->last_rinfo_serial = save_last_rinfo_serial;
- }
+ restrictinfo->clause = (Expr *) makeBoolConst(false, false);
cur_relid = -1;
while ((cur_relid = bms_next_member(join_relids, cur_relid)) >= 0)
diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c
index 0af26d6acf..0b6634f8b5 100644
--- a/src/backend/utils/adt/amutils.c
+++ b/src/backend/utils/adt/amutils.c
@@ -158,9 +158,6 @@ indexam_property(FunctionCallInfo fcinfo,
IndexAMProperty prop;
IndexAmRoutine *routine;
- /* Try to convert property name to enum (no error if not known) */
- prop = lookup_prop_name(propname);
-
/* If we have an index OID, look up the AM, and get # of columns too */
if (OidIsValid(index_oid))
{
@@ -199,6 +196,9 @@ indexam_property(FunctionCallInfo fcinfo,
if (routine == NULL)
PG_RETURN_NULL();
+ /* Try to convert property name to enum (no error if not known) */
+ prop = lookup_prop_name(propname);
+
/*
* If there's an AM property routine, give it a chance to override the
* generic logic. Proceed if it returns false.
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 860bbd40d4..7f6e64e78f 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -584,6 +584,14 @@ errfinish(const char *filename, int lineno, const char *funcname)
* worthy of panic, depending on which subprocess returns it.
*/
proc_exit(1);
+
+ /*
+ * Closes all of the calling process's open streams.
+ * On Windows, close and remove all temporary files created by tmpfile function.
+ */
+ #ifdef NDEBUG
+ fcloseall();
+ #endif
}
if (elevel >= PANIC)
@@ -596,6 +604,15 @@ errfinish(const char *filename, int lineno, const char *funcname)
* children...
*/
fflush(NULL);
+
+ /*
+ * Closes all of the calling process's open streams.
+ * On Windows, close and remove all temporary files created by tmpfile function.
+ */
+ #ifdef NDEBUG
+ fcloseall();
+ #endif
+
abort();
}
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 8a405ff122..2cf8b0be8f 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -356,7 +356,7 @@ readfile(const char *path, int *numlines)
if (len != statbuf.st_size)
{
/* oops, the file size changed between fstat and read */
- free(buffer);
+ pg_free(buffer);
return NULL;
}
@@ -397,7 +397,7 @@ readfile(const char *path, int *numlines)
}
result[n] = NULL;
- free(buffer);
+ pg_free(buffer);
return result;
}
@@ -1942,7 +1942,7 @@ GetPrivilegesToDelete(HANDLE hToken)
{
write_stderr(_("%s: could not get token information: error code %lu\n"),
progname, (unsigned long) GetLastError());
- free(tokenPrivs);
+ pg_free(tokenPrivs);
return NULL;
}
@@ -2168,7 +2168,7 @@ adjust_data_dir(void)
write_stderr(_("%s: could not determine the data directory using command \"%s\"\n"), progname, cmd);
exit(1);
}
- free(my_exec_path);
+ pg_free(my_exec_path);
/* strip trailing newline and carriage return */
(void) pg_strip_crlf(filename);
diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c
index 5150eb0532..ae2d0e5ed3 100644
--- a/src/bin/psql/variables.c
+++ b/src/bin/psql/variables.c
@@ -234,7 +234,7 @@ ParseVariableDouble(const char *value, const char *name, double *result, double
* too close to zero to have full precision, by checking for zero or real
* out-of-range values.
*/
- else if ((errno = ERANGE) &&
+ else if ((errno == ERANGE) &&
(dblval == 0.0 || dblval >= HUGE_VAL || dblval <= -HUGE_VAL))
{
if (name)
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index 7b8f7d4c52..9d5ff712e1 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -151,15 +151,15 @@ yesno_prompt(const char *question)
if (strcmp(resp, _(PG_YESLETTER)) == 0)
{
- free(resp);
+ pg_free(resp);
return true;
}
if (strcmp(resp, _(PG_NOLETTER)) == 0)
{
- free(resp);
+ pg_free(resp);
return false;
}
- free(resp);
+ pg_free(resp);
printf(_("Please answer \"%s\" or \"%s\".\n"),
_(PG_YESLETTER), _(PG_NOLETTER));
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index 81e6abfc46..853afde3ba 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -237,7 +237,7 @@ main(int argc, char *argv[])
fprintf(stderr, _("Passwords didn't match.\n"));
exit(1);
}
- free(pw2);
+ pg_free(pw2);
}
if (superuser == TRI_DEFAULT)
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index 860a0fcb46..d944876eea 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -348,13 +348,6 @@ reindex_one_database(ConnParams *cparams, ReindexType type,
process_list = get_parallel_tables_list(conn, process_type,
user_list, echo);
process_type = REINDEX_TABLE;
-
- /* Bail out if nothing to process */
- if (process_list == NULL)
- {
- PQfinish(conn);
- return;
- }
break;
case REINDEX_INDEX:
@@ -380,7 +373,6 @@ reindex_one_database(ConnParams *cparams, ReindexType type,
case REINDEX_SYSTEM:
/* not supported */
- process_list = NULL;
Assert(false);
break;
@@ -390,6 +382,13 @@ reindex_one_database(ConnParams *cparams, ReindexType type,
}
}
+ /* Bail out if nothing to process */
+ if (process_list == NULL)
+ {
+ PQfinish(conn);
+ return;
+ }
+
/*
* Adjust the number of concurrent connections depending on the items in
* the list. We choose the minimum between the number of concurrent
@@ -434,7 +433,7 @@ reindex_one_database(ConnParams *cparams, ReindexType type,
ParallelSlotSetHandler(free_slot, TableCommandResultHandler, NULL);
initPQExpBuffer(&sql);
- if (parallel && process_type == REINDEX_INDEX)
+ if (parallel && process_type == REINDEX_INDEX && indices_tables_cell)
{
/*
* For parallel index-level REINDEX, the indices of the same table
@@ -444,17 +443,16 @@ reindex_one_database(ConnParams *cparams, ReindexType type,
*/
gen_reindex_command(free_slot->connection, process_type, objname,
echo, verbose, concurrently, tablespace, &sql);
- while (indices_tables_cell->next &&
+ while (indices_tables_cell && indices_tables_cell->next &&
indices_tables_cell->val == indices_tables_cell->next->val)
{
- indices_tables_cell = indices_tables_cell->next;
cell = cell->next;
objname = cell->val;
appendPQExpBufferChar(&sql, '\n');
gen_reindex_command(free_slot->connection, process_type, objname,
echo, verbose, concurrently, tablespace, &sql);
+ indices_tables_cell = indices_tables_cell->next;
}
- indices_tables_cell = indices_tables_cell->next;
}
else
{
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index 935e6da3c1..5368ed4a89 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -536,12 +536,12 @@ vacuum_one_database(ConnParams *cparams,
bool failed = false;
const char *initcmd;
SimpleStringList *ret = NULL;
- const char *stage_commands[] = {
+ static const char *stage_commands[] = {
"SET default_statistics_target=1; SET vacuum_cost_delay=0;",
"SET default_statistics_target=10; RESET vacuum_cost_delay;",
"RESET default_statistics_target;"
};
- const char *stage_messages[] = {
+ static const char *stage_messages[] = {
gettext_noop("Generating minimal optimizer statistics (1 target)"),
gettext_noop("Generating medium optimizer statistics (10 targets)"),
gettext_noop("Generating default (full) optimizer statistics")
@@ -793,7 +793,6 @@ static SimpleStringList *
retrieve_objects(PGconn *conn, vacuumingOptions *vacopts,
SimpleStringList *objects, bool echo)
{
- PQExpBufferData buf;
PQExpBufferData catalog_query;
PGresult *res;
SimpleStringListCell *cell;
@@ -1031,28 +1030,23 @@ retrieve_objects(PGconn *conn, vacuumingOptions *vacopts,
appendPQExpBufferStr(&catalog_query, " ORDER BY c.relpages DESC;");
executeCommand(conn, "RESET search_path;", echo);
res = executeQuery(conn, catalog_query.data, echo);
- termPQExpBuffer(&catalog_query);
PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo));
+ termPQExpBuffer(&catalog_query);
/*
* Build qualified identifiers for each table, including the column list
* if given.
*/
- initPQExpBuffer(&buf);
for (int i = 0; i < PQntuples(res); i++)
{
- appendPQExpBufferStr(&buf,
+ simple_string_list_append(found_objs,
fmtQualifiedIdEnc(PQgetvalue(res, i, 1),
PQgetvalue(res, i, 0),
PQclientEncoding(conn)));
if (objects_listed && !PQgetisnull(res, i, 2))
- appendPQExpBufferStr(&buf, PQgetvalue(res, i, 2));
-
- simple_string_list_append(found_objs, buf.data);
- resetPQExpBuffer(&buf);
+ simple_string_list_append(found_objs, PQgetvalue(res, i, 2));
}
- termPQExpBuffer(&buf);
PQclear(res);
return found_objs;
diff --git a/src/common/username.c b/src/common/username.c
index ae5f02d96b..aa5f236d88 100644
--- a/src/common/username.c
+++ b/src/common/username.c
@@ -48,9 +48,12 @@ get_user_name(char **errstr)
return pw->pw_name;
#else
- /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
+ #include "Lmcons.h"
+
+ /* Microsoft recommends buffer size of UNLEN + 1 */
+ /* UNLEN is defined in Lmcons.h */
/* "static" variable remains after function exit */
- static char username[256 + 1];
+ static char username[UNLEN + 1];
DWORD len = sizeof(username);
*errstr = NULL;
diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h
index 327274c234..91211c7abc 100644
--- a/src/include/lib/simplehash.h
+++ b/src/include/lib/simplehash.h
@@ -149,7 +149,7 @@ typedef struct SH_TYPE
* tables. Note that the maximum number of elements is lower
* (SH_MAX_FILLFACTOR)
*/
- uint64 size;
+ uint32 size;
/* how many elements have valid contents */
uint32 members;
@@ -204,8 +204,8 @@ SH_SCOPE void SH_DESTROY(SH_TYPE * tb);
/* void <prefix>_reset(<prefix>_hash *tb) */
SH_SCOPE void SH_RESET(SH_TYPE * tb);
-/* void <prefix>_grow(<prefix>_hash *tb, uint64 newsize) */
-SH_SCOPE void SH_GROW(SH_TYPE * tb, uint64 newsize);
+/* void <prefix>_grow(<prefix>_hash *tb, uint63 newsize) */
+SH_SCOPE void SH_GROW(SH_TYPE * tb, uint32 newsize);
/* <element> *<prefix>_insert(<prefix>_hash *tb, <key> key, bool *found) */
SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found);
@@ -256,7 +256,7 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb);
#endif
/* max data array size,we allow up to PG_UINT32_MAX buckets, including 0 */
-#define SH_MAX_SIZE (((uint64) PG_UINT32_MAX) + 1)
+#define SH_MAX_SIZE PG_UINT32_MAX
/* normal fillfactor, unless already close to maximum */
#ifndef SH_FILLFACTOR
@@ -307,10 +307,10 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb);
* Compute allocation size for hashtable. Result can be passed to
* SH_UPDATE_PARAMETERS.
*/
-static inline uint64
-SH_COMPUTE_SIZE(uint64 newsize)
+static inline uint32
+SH_COMPUTE_SIZE(uint32 newsize)
{
- uint64 size;
+ uint32 size;
/* supporting zero sized hashes would complicate matters */
size = Max(newsize, 2);
@@ -326,7 +326,7 @@ SH_COMPUTE_SIZE(uint64 newsize)
if (unlikely((((uint64) sizeof(SH_ELEMENT_TYPE)) * size) >= SIZE_MAX / 2))
sh_error("hash table too large");
- return size;
+ return (uint32) size;
}
/*
@@ -334,9 +334,9 @@ SH_COMPUTE_SIZE(uint64 newsize)
* the hashtable.
*/
static inline void
-SH_UPDATE_PARAMETERS(SH_TYPE * tb, uint64 newsize)
+SH_UPDATE_PARAMETERS(SH_TYPE * tb, uint32 newsize)
{
- uint64 size = SH_COMPUTE_SIZE(newsize);
+ uint32 size = SH_COMPUTE_SIZE(newsize);
/* now set size */
tb->size = size;
@@ -446,7 +446,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, void *private_data)
#endif
{
SH_TYPE *tb;
- uint64 size;
+ uint32 size;
#ifdef SH_RAW_ALLOCATOR
tb = (SH_TYPE *) SH_RAW_ALLOCATOR(sizeof(SH_TYPE));
@@ -491,9 +491,9 @@ SH_RESET(SH_TYPE * tb)
* performance-wise, when known at some point.
*/
SH_SCOPE void
-SH_GROW(SH_TYPE * tb, uint64 newsize)
+SH_GROW(SH_TYPE * tb, uint32 newsize)
{
- uint64 oldsize = tb->size;
+ uint32 oldsize = tb->size;
SH_ELEMENT_TYPE *olddata = tb->data;
SH_ELEMENT_TYPE *newdata;
uint32 i;
@@ -982,7 +982,7 @@ SH_DELETE_ITEM(SH_TYPE * tb, SH_ELEMENT_TYPE * entry)
SH_SCOPE void
SH_START_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter)
{
- uint64 startelem = PG_UINT64_MAX;
+ uint32 startelem = PG_UINT32_MAX;
/*
* Search for the first empty element. As deletions during iterations are
diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h
index 62554ce685..569646c13e 100644
--- a/src/include/port/pg_bitutils.h
+++ b/src/include/port/pg_bitutils.h
@@ -301,7 +301,7 @@ pg_ceil_log2_64(uint64 num)
#ifdef TRY_POPCNT_FAST
/* Attempt to use the POPCNT instruction, but perform a runtime check first */
extern PGDLLIMPORT int (*pg_popcount32) (uint32 word);
-extern PGDLLIMPORT int (*pg_popcount64) (uint64 word);
+extern PGDLLIMPORT uint64 (*pg_popcount64) (uint64 word);
extern PGDLLIMPORT uint64 (*pg_popcount_optimized) (const char *buf, int bytes);
extern PGDLLIMPORT uint64 (*pg_popcount_masked_optimized) (const char *buf, int bytes, bits8 mask);
@@ -318,7 +318,7 @@ extern uint64 pg_popcount_masked_avx512(const char *buf, int bytes, bits8 mask);
#else
/* Use a portable implementation -- no need for a function pointer. */
extern int pg_popcount32(uint32 word);
-extern int pg_popcount64(uint64 word);
+extern uint64 pg_popcount64(uint64 word);
extern uint64 pg_popcount_optimized(const char *buf, int bytes);
extern uint64 pg_popcount_masked_optimized(const char *buf, int bytes, bits8 mask);
diff --git a/src/include/storage/read_stream.h b/src/include/storage/read_stream.h
index c11d8ce330..5af801969b 100644
--- a/src/include/storage/read_stream.h
+++ b/src/include/storage/read_stream.h
@@ -70,6 +70,7 @@ extern ReadStream *read_stream_begin_relation(int flags,
extern Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data);
extern BlockNumber read_stream_next_block(ReadStream *stream,
BufferAccessStrategy *strategy);
+extern size_t read_stream_per_buffer_data_size(ReadStream *stream);
extern ReadStream *read_stream_begin_smgr_relation(int flags,
BufferAccessStrategy strategy,
SMgrRelation smgr,
@@ -81,4 +82,67 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags,
extern void read_stream_reset(ReadStream *stream);
extern void read_stream_end(ReadStream *stream);
+/*
+ * Get the next buffer from a stream that is not using per-buffer data.
+ */
+static inline Buffer
+read_stream_get_buffer(ReadStream *stream)
+{
+ Assert(read_stream_per_buffer_data_size(stream) == 0);
+ return read_stream_next_buffer(stream, NULL);
+}
+
+/*
+ * Helper for read_stream_get_buffer_and_value().
+ */
+static inline Buffer
+read_stream_get_buffer_and_value_with_size(ReadStream *stream,
+ void *output_data,
+ size_t output_data_size)
+{
+ Buffer buffer;
+ void *per_buffer_data;
+
+ Assert(read_stream_per_buffer_data_size(stream) == output_data_size);
+ buffer = read_stream_next_buffer(stream, &per_buffer_data);
+ if (buffer != InvalidBuffer)
+ memcpy(output_data, per_buffer_data, output_data_size);
+
+ return buffer;
+}
+
+/*
+ * Get the next buffer and a copy of the associated per-buffer data.
+ * InvalidBuffer means end-of-stream, and in that case the per-buffer data is
+ * undefined. Example of use:
+ *
+ * int my_int;
+ *
+ * buf = read_stream_get_buffer_and_value(stream, &my_int);
+ */
+#define read_stream_get_buffer_and_value(stream, vp) \
+ read_stream_get_buffer_and_value_with_size((stream), (vp), sizeof(*(vp)))
+
+/*
+ * Get the next buffer and a pointer to the associated per-buffer data. This
+ * avoids casts in the calling code, and asserts that we received a pointer to
+ * a pointer to a type that doesn't exceed the storage size. For example:
+ *
+ * int *my_int_p;
+ *
+ * buf = read_stream_get_buffer_and_pointer(stream, &my_int_p);
+ */
+#define read_stream_get_buffer_and_pointer(stream, pointer) \
+ (AssertMacro(sizeof(**(pointer)) <= read_stream_per_buffer_data_size(stream)), \
+ read_stream_next_buffer((stream), ((void **) (pointer))))
+
+/*
+ * Set the per-buffer data by value. This can be called from inside a
+ * callback that is returning block numbers. It asserts that the value's size
+ * matches the available space.
+ */
+#define read_stream_put_value(stream, per_buffer_data, value) \
+ (AssertMacro(sizeof(value) == read_stream_per_buffer_data_size(stream)), \
+ memcpy((per_buffer_data), &(value), sizeof(value)))
+
#endif /* READ_STREAM_H */
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index d78445c70a..abc99caef2 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -580,7 +580,7 @@ int
pqReadData(PGconn *conn)
{
int someread = 0;
- int nread;
+ ssize_t nread;
if (conn->sock == PGINVALID_SOCKET)
{
@@ -838,7 +838,7 @@ pqSendSome(PGconn *conn, int len)
/* while there's still data to send */
while (len > 0)
{
- int sent;
+ ssize_t sent;
#ifndef WIN32
sent = pqsecure_write(conn, ptr, len);
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 5bb9d9779d..f0eaf8d4f1 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -118,9 +118,6 @@ pgtls_read(PGconn *conn, void *ptr, size_t len)
{
ssize_t n;
int result_errno = 0;
- char sebuf[PG_STRERROR_R_BUFLEN];
- int err;
- unsigned long ecode;
rloop:
@@ -136,91 +133,98 @@ rloop:
SOCK_ERRNO_SET(0);
ERR_clear_error();
n = SSL_read(conn->ssl, ptr, len);
- err = SSL_get_error(conn->ssl, n);
-
- /*
- * Other clients of OpenSSL may fail to call ERR_get_error(), but we
- * always do, so as to not cause problems for OpenSSL clients that don't
- * call ERR_clear_error() defensively. Be sure that this happens by
- * calling now. SSL_get_error() relies on the OpenSSL per-thread error
- * queue being intact, so this is the earliest possible point
- * ERR_get_error() may be called.
- */
- ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
- switch (err)
+ if (n <= 0)
{
- case SSL_ERROR_NONE:
- if (n < 0)
- {
- /* Not supposed to happen, so we don't translate the msg */
- appendPQExpBufferStr(&conn->errorMessage,
- "SSL_read failed but did not provide error information\n");
- /* assume the connection is broken */
- result_errno = ECONNRESET;
- }
- break;
- case SSL_ERROR_WANT_READ:
- n = 0;
- break;
- case SSL_ERROR_WANT_WRITE:
+ char sebuf[PG_STRERROR_R_BUFLEN];
+ int err;
+ unsigned long ecode;
- /*
- * Returning 0 here would cause caller to wait for read-ready,
- * which is not correct since what SSL wants is wait for
- * write-ready. The former could get us stuck in an infinite
- * wait, so don't risk it; busy-loop instead.
- */
- goto rloop;
- case SSL_ERROR_SYSCALL:
- if (n < 0 && SOCK_ERRNO != 0)
- {
- result_errno = SOCK_ERRNO;
- if (result_errno == EPIPE ||
- result_errno == ECONNRESET)
- libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
- "\tThis probably means the server terminated abnormally\n"
- "\tbefore or while processing the request.");
+ err = SSL_get_error(conn->ssl, n);
+
+ /*
+ * Other clients of OpenSSL may fail to call ERR_get_error(), but we
+ * always do, so as to not cause problems for OpenSSL clients that don't
+ * call ERR_clear_error() defensively. Be sure that this happens by
+ * calling now. SSL_get_error() relies on the OpenSSL per-thread error
+ * queue being intact, so this is the earliest possible point
+ * ERR_get_error() may be called.
+ */
+ ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
+ switch (err)
+ {
+ case SSL_ERROR_NONE:
+ if (n < 0)
+ {
+ /* Not supposed to happen, so we don't translate the msg */
+ appendPQExpBufferStr(&conn->errorMessage,
+ "SSL_read failed but did not provide error information\n");
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ }
+ break;
+ case SSL_ERROR_WANT_READ:
+ n = 0;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+
+ /*
+ * Returning 0 here would cause caller to wait for read-ready,
+ * which is not correct since what SSL wants is wait for
+ * write-ready. The former could get us stuck in an infinite
+ * wait, so don't risk it; busy-loop instead.
+ */
+ goto rloop;
+ case SSL_ERROR_SYSCALL:
+ if (n < 0 && SOCK_ERRNO != 0)
+ {
+ result_errno = SOCK_ERRNO;
+ if (result_errno == EPIPE ||
+ result_errno == ECONNRESET)
+ libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
+ "\tThis probably means the server terminated abnormally\n"
+ "\tbefore or while processing the request.");
+ else
+ libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
+ SOCK_STRERROR(result_errno,
+ sebuf, sizeof(sebuf)));
+ }
else
- libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
- SOCK_STRERROR(result_errno,
- sebuf, sizeof(sebuf)));
- }
- else
- {
- libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
- /* assume the connection is broken */
+ {
+ libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ n = -1;
+ }
+ break;
+ case SSL_ERROR_SSL:
+ {
+ char *errm = SSLerrmessage(ecode);
+
+ libpq_append_conn_error(conn, "SSL error: %s", errm);
+ SSLerrfree(errm);
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ n = -1;
+ break;
+ }
+ case SSL_ERROR_ZERO_RETURN:
+
+ /*
+ * Per OpenSSL documentation, this error code is only returned for
+ * a clean connection closure, so we should not report it as a
+ * server crash.
+ */
+ libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
result_errno = ECONNRESET;
n = -1;
- }
- break;
- case SSL_ERROR_SSL:
- {
- char *errm = SSLerrmessage(ecode);
-
- libpq_append_conn_error(conn, "SSL error: %s", errm);
- SSLerrfree(errm);
+ break;
+ default:
+ libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
/* assume the connection is broken */
result_errno = ECONNRESET;
n = -1;
break;
- }
- case SSL_ERROR_ZERO_RETURN:
-
- /*
- * Per OpenSSL documentation, this error code is only returned for
- * a clean connection closure, so we should not report it as a
- * server crash.
- */
- libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
- result_errno = ECONNRESET;
- n = -1;
- break;
- default:
- libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
- /* assume the connection is broken */
- result_errno = ECONNRESET;
- n = -1;
- break;
+ }
}
/* ensure we return the intended errno to caller */
@@ -240,93 +244,97 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
{
ssize_t n;
int result_errno = 0;
- char sebuf[PG_STRERROR_R_BUFLEN];
- int err;
- unsigned long ecode;
SOCK_ERRNO_SET(0);
ERR_clear_error();
n = SSL_write(conn->ssl, ptr, len);
- err = SSL_get_error(conn->ssl, n);
- ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
- switch (err)
+ if (n <= 0)
{
- case SSL_ERROR_NONE:
- if (n < 0)
- {
- /* Not supposed to happen, so we don't translate the msg */
- appendPQExpBufferStr(&conn->errorMessage,
- "SSL_write failed but did not provide error information\n");
- /* assume the connection is broken */
- result_errno = ECONNRESET;
- }
- break;
- case SSL_ERROR_WANT_READ:
+ char sebuf[PG_STRERROR_R_BUFLEN];
+ int err;
+ unsigned long ecode;
- /*
- * Returning 0 here causes caller to wait for write-ready, which
- * is not really the right thing, but it's the best we can do.
- */
- n = 0;
- break;
- case SSL_ERROR_WANT_WRITE:
- n = 0;
- break;
- case SSL_ERROR_SYSCALL:
+ err = SSL_get_error(conn->ssl, n);
+ ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
+ switch (err)
+ {
+ case SSL_ERROR_NONE:
+ if (n < 0)
+ {
+ /* Not supposed to happen, so we don't translate the msg */
+ appendPQExpBufferStr(&conn->errorMessage,
+ "SSL_write failed but did not provide error information\n");
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ }
+ break;
+ case SSL_ERROR_WANT_READ:
- /*
- * 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)
- libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
- "\tThis probably means the server terminated abnormally\n"
- "\tbefore or while processing the request.");
+ /*
+ * Returning 0 here causes caller to wait for write-ready, which
+ * is not really the right thing, but it's the best we can do.
+ */
+ n = 0;
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ n = 0;
+ break;
+ case SSL_ERROR_SYSCALL:
+
+ /*
+ * 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)
+ libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
+ "\tThis probably means the server terminated abnormally\n"
+ "\tbefore or while processing the request.");
+ else
+ libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
+ SOCK_STRERROR(result_errno,
+ sebuf, sizeof(sebuf)));
+ }
else
- libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
- SOCK_STRERROR(result_errno,
- sebuf, sizeof(sebuf)));
- }
- else
- {
- libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
- /* assume the connection is broken */
+ {
+ libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ n = -1;
+ }
+ break;
+ case SSL_ERROR_SSL:
+ {
+ char *errm = SSLerrmessage(ecode);
+
+ libpq_append_conn_error(conn, "SSL error: %s", errm);
+ SSLerrfree(errm);
+ /* assume the connection is broken */
+ result_errno = ECONNRESET;
+ n = -1;
+ break;
+ }
+ case SSL_ERROR_ZERO_RETURN:
+
+ /*
+ * Per OpenSSL documentation, this error code is only returned for
+ * a clean connection closure, so we should not report it as a
+ * server crash.
+ */
+ libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
result_errno = ECONNRESET;
n = -1;
- }
- break;
- case SSL_ERROR_SSL:
- {
- char *errm = SSLerrmessage(ecode);
-
- libpq_append_conn_error(conn, "SSL error: %s", errm);
- SSLerrfree(errm);
+ break;
+ default:
+ libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
/* assume the connection is broken */
result_errno = ECONNRESET;
n = -1;
break;
- }
- case SSL_ERROR_ZERO_RETURN:
-
- /*
- * Per OpenSSL documentation, this error code is only returned for
- * a clean connection closure, so we should not report it as a
- * server crash.
- */
- libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
- result_errno = ECONNRESET;
- n = -1;
- break;
- default:
- libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
- /* assume the connection is broken */
- result_errno = ECONNRESET;
- n = -1;
- break;
+ }
}
/* ensure we return the intended errno to caller */
diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c
index 5677525693..b375326f92 100644
--- a/src/port/pg_bitutils.c
+++ b/src/port/pg_bitutils.c
@@ -104,23 +104,23 @@ const uint8 pg_number_of_ones[256] = {
};
static inline int pg_popcount32_slow(uint32 word);
-static inline int pg_popcount64_slow(uint64 word);
+static inline uint64 pg_popcount64_slow(uint64 word);
static uint64 pg_popcount_slow(const char *buf, int bytes);
static uint64 pg_popcount_masked_slow(const char *buf, int bytes, bits8 mask);
#ifdef TRY_POPCNT_FAST
static bool pg_popcount_available(void);
static int pg_popcount32_choose(uint32 word);
-static int pg_popcount64_choose(uint64 word);
+static uint64 pg_popcount64_choose(uint64 word);
static uint64 pg_popcount_choose(const char *buf, int bytes);
static uint64 pg_popcount_masked_choose(const char *buf, int bytes, bits8 mask);
static inline int pg_popcount32_fast(uint32 word);
-static inline int pg_popcount64_fast(uint64 word);
+static inline uint64 pg_popcount64_fast(uint64 word);
static uint64 pg_popcount_fast(const char *buf, int bytes);
static uint64 pg_popcount_masked_fast(const char *buf, int bytes, bits8 mask);
int (*pg_popcount32) (uint32 word) = pg_popcount32_choose;
-int (*pg_popcount64) (uint64 word) = pg_popcount64_choose;
+uint64 (*pg_popcount64) (uint64 word) = pg_popcount64_choose;
uint64 (*pg_popcount_optimized) (const char *buf, int bytes) = pg_popcount_choose;
uint64 (*pg_popcount_masked_optimized) (const char *buf, int bytes, bits8 mask) = pg_popcount_masked_choose;
#endif /* TRY_POPCNT_FAST */
@@ -186,7 +186,7 @@ pg_popcount32_choose(uint32 word)
return pg_popcount32(word);
}
-static int
+static uint64
pg_popcount64_choose(uint64 word)
{
choose_popcount_functions();
@@ -228,7 +228,7 @@ __asm__ __volatile__(" popcntl %1,%0\n":"=q"(res):"rm"(word):"cc");
* pg_popcount64_fast
* Return the number of 1 bits set in word
*/
-static inline int
+static inline uint64
pg_popcount64_fast(uint64 word)
{
#ifdef _MSC_VER
@@ -237,7 +237,7 @@ pg_popcount64_fast(uint64 word)
uint64 res;
__asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc");
- return (int) res;
+ return res;
#endif
}
@@ -366,7 +366,7 @@ pg_popcount32_slow(uint32 word)
* pg_popcount64_slow
* Return the number of 1 bits set in word
*/
-static inline int
+static inline uint64
pg_popcount64_slow(uint64 word)
{
#ifdef HAVE__BUILTIN_POPCOUNT
@@ -378,7 +378,7 @@ pg_popcount64_slow(uint64 word)
#error "cannot find integer of the same size as uint64_t"
#endif
#else /* !HAVE__BUILTIN_POPCOUNT */
- int result = 0;
+ uint64 result = 0;
while (word != 0)
{
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index f8f2018ea0..a040428204 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -328,7 +328,7 @@ static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target);
static void fmtfloat(double value, char type, int forcesign,
int leftjust, int minlen, int zpad, int precision, int pointflag,
PrintfTarget *target);
-static void dostr(const char *str, int slen, PrintfTarget *target);
+static void dostr(const char *str, size_t slen, PrintfTarget *target);
static void dopr_outch(int c, PrintfTarget *target);
static void dopr_outchmulti(int c, int slen, PrintfTarget *target);
static int adjust_sign(int is_negative, int forcesign, int *signvalue);
@@ -1410,7 +1410,7 @@ fail:
static void
-dostr(const char *str, int slen, PrintfTarget *target)
+dostr(const char *str, size_t slen, PrintfTarget *target)
{
/* fast path for common case of slen == 1 */
if (slen == 1)
@@ -1421,13 +1421,13 @@ dostr(const char *str, int slen, PrintfTarget *target)
while (slen > 0)
{
- int avail;
+ size_t avail;
if (target->bufend != NULL)
avail = target->bufend - target->bufptr;
else
avail = slen;
- if (avail <= 0)
+ if (avail == 0)
{
/* buffer full, can we dump to stream? */
if (target->stream == NULL)
diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.c
index 7c0982439d..3ba73d71a7 100644
--- a/src/port/win32setlocale.c
+++ b/src/port/win32setlocale.c
@@ -146,10 +146,10 @@ map_locale(const struct locale_map *map, const char *locale)
if (match_start)
{
/* Found a match. Replace the matched string. */
- int matchpos = match_start - locale;
- int replacementlen = strlen(replacement);
+ size_t matchpos = match_start - locale;
+ size_t replacementlen = strlen(replacement);
char *rest = match_end;
- int restlen = strlen(rest);
+ size_t restlen = strlen(rest);
/* check that the result fits in the static buffer */
if (matchpos + replacementlen + restlen + 1 > MAX_LOCALE_NAME_LEN)
diff --git a/src/test/modules/test_escape/test_escape.c b/src/test/modules/test_escape/test_escape.c
index f6b3644897..47fd75f008 100644
--- a/src/test/modules/test_escape/test_escape.c
+++ b/src/test/modules/test_escape/test_escape.c
@@ -143,7 +143,8 @@ escape_string_conn(PGconn *conn, PQExpBuffer target,
size_t sz;
appendPQExpBufferChar(target, '\'');
- enlargePQExpBuffer(target, unescaped_len * 2 + 1);
+ if (!enlargePQExpBuffer(target, unescaped_len * 2 + 1))
+ return false;
sz = PQescapeStringConn(conn, target->data + target->len,
unescaped, unescaped_len,
&error);
@@ -173,7 +174,8 @@ escape_string(PGconn *conn, PQExpBuffer target,
size_t sz;
appendPQExpBufferChar(target, '\'');
- enlargePQExpBuffer(target, unescaped_len * 2 + 1);
+ if (!enlargePQExpBuffer(target, unescaped_len * 2 + 1))
+ return false;
sz = PQescapeString(target->data + target->len,
unescaped, unescaped_len);
target->len += sz;