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;
