Wrong defeinition of pq_putmessage_noblock since 9.5

Started by Kyotaro HORIGUCHIover 9 years ago12 messages
#1Kyotaro HORIGUCHI
horiguchi.kyotaro@lab.ntt.co.jp
1 attachment(s)

Hello,

While testing replication for 9.5, we found that repl-master can
ignore wal_sender_timeout and seemingly waits for TCP
retransmission timeout for the case of sudden power-off of a
standby.

My investigation told me that the immediate cause could be that
secure_write() is called with *blocking mode* (that is,
port->noblock = false) under *pq_putmessage_noblock* macro called
from XLogSendPhysical().

libpq.h of 9.5 and newer defines it as the following,

#define pq_putmessage(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))
#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))

which is apparently should be the following.

#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage_noblock(msgtype, s, len))

The attached patch fixes it.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachments:

0001-Fix-the-defeinition-of-pq_putmessage_noblock-macro.patchtext/x-patch; charset=us-asciiDownload
From b15db80734215b7e3b4bbae849cf89ffd990e8be Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Thu, 28 Jul 2016 18:28:57 +0900
Subject: [PATCH] Fix the defeinition of pq_putmessage_noblock macro.

pq_putmessage_noblock marcro is mistakenly defined as the same with
pg_putmessage. Fix it.
---
 src/include/libpq/libpq.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 547d3b8..18052cb 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -43,7 +43,7 @@ extern PGDLLIMPORT PQcommMethods *PqCommMethods;
 #define pq_putmessage(msgtype, s, len) \
 	(PqCommMethods->putmessage(msgtype, s, len))
 #define pq_putmessage_noblock(msgtype, s, len) \
-	(PqCommMethods->putmessage(msgtype, s, len))
+	(PqCommMethods->putmessage_noblock(msgtype, s, len))
 #define pq_startcopyout() (PqCommMethods->startcopyout())
 #define pq_endcopyout(errorAbort) (PqCommMethods->endcopyout(errorAbort))
 
-- 
1.8.3.1

#2Fujii Masao
masao.fujii@gmail.com
In reply to: Kyotaro HORIGUCHI (#1)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

On Thu, Jul 28, 2016 at 6:52 PM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

Hello,

While testing replication for 9.5, we found that repl-master can
ignore wal_sender_timeout and seemingly waits for TCP
retransmission timeout for the case of sudden power-off of a
standby.

My investigation told me that the immediate cause could be that
secure_write() is called with *blocking mode* (that is,
port->noblock = false) under *pq_putmessage_noblock* macro called
from XLogSendPhysical().

libpq.h of 9.5 and newer defines it as the following,

#define pq_putmessage(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))
#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))

which is apparently should be the following.

#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage_noblock(msgtype, s, len))

The attached patch fixes it.

Good catch! Barring objection, I will push this to both master and 9.5.

Regards,

--
Fujii Masao

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Fujii Masao
masao.fujii@gmail.com
In reply to: Fujii Masao (#2)
1 attachment(s)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

On Thu, Jul 28, 2016 at 9:08 PM, Fujii Masao <masao.fujii@gmail.com> wrote:

On Thu, Jul 28, 2016 at 6:52 PM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

Hello,

While testing replication for 9.5, we found that repl-master can
ignore wal_sender_timeout and seemingly waits for TCP
retransmission timeout for the case of sudden power-off of a
standby.

My investigation told me that the immediate cause could be that
secure_write() is called with *blocking mode* (that is,
port->noblock = false) under *pq_putmessage_noblock* macro called
from XLogSendPhysical().

libpq.h of 9.5 and newer defines it as the following,

#define pq_putmessage(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))
#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage(msgtype, s, len))

which is apparently should be the following.

#define pq_putmessage_noblock(msgtype, s, len) \
(PqCommMethods->putmessage_noblock(msgtype, s, len))

The attached patch fixes it.

Good catch! Barring objection, I will push this to both master and 9.5.

Regarding this patch, while reading pqcomm.c, I found the following things.

1. socket_comm_reset() calls pq_endcopyout().
I think that socket_endcopyout() should be called, instead.

2. socket_putmessage_noblock() calls pq_putmessage().
I think that socket_putmessage() should be called, instead.

3. Several source comments in pqcomm.c have not been updated.
Some comments still use the old function name like pq_putmessage().

Attached patch fixes the above issues.

Regards,

--
Fujii Masao

Attachments:

pqcomm.patchtext/x-patch; charset=US-ASCII; name=pqcomm.patchDownload
*** a/src/backend/libpq/pqcomm.c
--- b/src/backend/libpq/pqcomm.c
***************
*** 18,24 ****
   * NOTE: generally, it's a bad idea to emit outgoing messages directly with
   * pq_putbytes(), especially if the message would require multiple calls
   * to send.  Instead, use the routines in pqformat.c to construct the message
!  * in a buffer and then emit it in one call to pq_putmessage.  This ensures
   * that the channel will not be clogged by an incomplete message if execution
   * is aborted by ereport(ERROR) partway through the message.  The only
   * non-libpq code that should call pq_putbytes directly is old-style COPY OUT.
--- 18,24 ----
   * NOTE: generally, it's a bad idea to emit outgoing messages directly with
   * pq_putbytes(), especially if the message would require multiple calls
   * to send.  Instead, use the routines in pqformat.c to construct the message
!  * in a buffer and then emit it in one call to socket_putmessage.  This ensures
   * that the channel will not be clogged by an incomplete message if execution
   * is aborted by ereport(ERROR) partway through the message.  The only
   * non-libpq code that should call pq_putbytes directly is old-style COPY OUT.
***************
*** 44,50 ****
   *		StreamClose			- Close a client/backend connection
   *		TouchSocketFiles	- Protect socket files against /tmp cleaners
   *		pq_init			- initialize libpq at backend startup
!  *		pq_comm_reset	- reset libpq during error recovery
   *		pq_close		- shutdown libpq at backend exit
   *
   * low-level I/O:
--- 44,50 ----
   *		StreamClose			- Close a client/backend connection
   *		TouchSocketFiles	- Protect socket files against /tmp cleaners
   *		pq_init			- initialize libpq at backend startup
!  *		socket_comm_reset	- reset libpq during error recovery
   *		pq_close		- shutdown libpq at backend exit
   *
   * low-level I/O:
***************
*** 53,68 ****
   *		pq_getmessage	- get a message with length word from connection
   *		pq_getbyte		- get next byte from connection
   *		pq_peekbyte		- peek at next byte from connection
!  *		pq_putbytes		- send bytes to connection (not flushed until pq_flush)
!  *		pq_flush		- flush pending output
!  *		pq_flush_if_writable - flush pending output if writable without blocking
   *		pq_getbyte_if_available - get a byte if available without blocking
   *
   * message-level I/O (and old-style-COPY-OUT cruft):
!  *		pq_putmessage	- send a normal message (suppressed in COPY OUT mode)
!  *		pq_putmessage_noblock - buffer a normal message (suppressed in COPY OUT)
!  *		pq_startcopyout - inform libpq that a COPY OUT transfer is beginning
!  *		pq_endcopyout	- end a COPY OUT transfer
   *
   *------------------------
   */
--- 53,68 ----
   *		pq_getmessage	- get a message with length word from connection
   *		pq_getbyte		- get next byte from connection
   *		pq_peekbyte		- peek at next byte from connection
!  *		pq_putbytes		- send bytes to connection (not flushed until socket_flush)
!  *		socket_flush		- flush pending output
!  *		socket_flush_if_writable - flush pending output if writable without blocking
   *		pq_getbyte_if_available - get a byte if available without blocking
   *
   * message-level I/O (and old-style-COPY-OUT cruft):
!  *		socket_putmessage	- send a normal message (suppressed in COPY OUT mode)
!  *		socket_putmessage_noblock - buffer a normal message (suppressed in COPY OUT)
!  *		socket_startcopyout - inform libpq that a COPY OUT transfer is beginning
!  *		socket_endcopyout	- end a COPY OUT transfer
   *
   *------------------------
   */
***************
*** 109,115 **** static List *sock_paths = NIL;
   * Buffers for low-level I/O.
   *
   * The receive buffer is fixed size. Send buffer is usually 8k, but can be
!  * enlarged by pq_putmessage_noblock() if the message doesn't fit otherwise.
   */
  
  #define PQ_SEND_BUFFER_SIZE 8192
--- 109,115 ----
   * Buffers for low-level I/O.
   *
   * The receive buffer is fixed size. Send buffer is usually 8k, but can be
!  * enlarged by socket_putmessage_noblock() if the message doesn't fit otherwise.
   */
  
  #define PQ_SEND_BUFFER_SIZE 8192
***************
*** 223,229 **** socket_comm_reset(void)
  	/* Do not throw away pending data, but do reset the busy flag */
  	PqCommBusy = false;
  	/* We can abort any old-style COPY OUT, too */
! 	pq_endcopyout(true);
  }
  
  /* --------------------------------
--- 223,229 ----
  	/* Do not throw away pending data, but do reset the busy flag */
  	PqCommBusy = false;
  	/* We can abort any old-style COPY OUT, too */
! 	socket_endcopyout(true);
  }
  
  /* --------------------------------
***************
*** 1302,1308 **** pq_getmessage(StringInfo s, int maxlen)
  
  
  /* --------------------------------
!  *		pq_putbytes		- send bytes to connection (not flushed until pq_flush)
   *
   *		returns 0 if OK, EOF if trouble
   * --------------------------------
--- 1302,1308 ----
  
  
  /* --------------------------------
!  *		pq_putbytes		- send bytes to connection (not flushed until socket_flush)
   *
   *		returns 0 if OK, EOF if trouble
   * --------------------------------
***************
*** 1444,1450 **** internal_flush(void)
  }
  
  /* --------------------------------
!  *		pq_flush_if_writable - flush pending output if writable without blocking
   *
   * Returns 0 if OK, or EOF if trouble.
   * --------------------------------
--- 1444,1450 ----
  }
  
  /* --------------------------------
!  *		socket_flush_if_writable - flush pending output if writable without blocking
   *
   * Returns 0 if OK, or EOF if trouble.
   * --------------------------------
***************
*** 1542,1548 **** fail:
  }
  
  /* --------------------------------
!  *		pq_putmessage_noblock	- like pq_putmessage, but never blocks
   *
   *		If the output buffer is too small to hold the message, the buffer
   *		is enlarged.
--- 1542,1548 ----
  }
  
  /* --------------------------------
!  *		socket_putmessage_noblock	- like socket_putmessage, but never blocks
   *
   *		If the output buffer is too small to hold the message, the buffer
   *		is enlarged.
***************
*** 1563,1569 **** socket_putmessage_noblock(char msgtype, const char *s, size_t len)
  		PqSendBuffer = repalloc(PqSendBuffer, required);
  		PqSendBufferSize = required;
  	}
! 	res = pq_putmessage(msgtype, s, len);
  	Assert(res == 0);			/* should not fail when the message fits in
  								 * buffer */
  }
--- 1563,1569 ----
  		PqSendBuffer = repalloc(PqSendBuffer, required);
  		PqSendBufferSize = required;
  	}
! 	res = socket_putmessage(msgtype, s, len);
  	Assert(res == 0);			/* should not fail when the message fits in
  								 * buffer */
  }
#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fujii Masao (#3)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

Fujii Masao <masao.fujii@gmail.com> writes:

3. Several source comments in pqcomm.c have not been updated.
Some comments still use the old function name like pq_putmessage().

Attached patch fixes the above issues.

I dunno, this seems like it's doubling down on some extremely poor
decisions. Why is it that you now have to flip a coin to guess whether
the prefix is pq_ or socket_ for functions in this module? I would
rather see that renaming reverted.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Kyotaro HORIGUCHI
horiguchi.kyotaro@lab.ntt.co.jp
In reply to: Tom Lane (#4)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

At Thu, 28 Jul 2016 10:46:00 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <4313.1469717160@sss.pgh.pa.us>

Fujii Masao <masao.fujii@gmail.com> writes:

3. Several source comments in pqcomm.c have not been updated.
Some comments still use the old function name like pq_putmessage().

Attached patch fixes the above issues.

I dunno, this seems like it's doubling down on some extremely poor
decisions. Why is it that you now have to flip a coin to guess whether
the prefix is pq_ or socket_ for functions in this module? I would
rather see that renaming reverted.

The set of functions in PQcommMethods doesn't seem clean. They
are choosed arbitrary just so that other pq_* functions used in
parallel workers will work as expected. I suppose that it needs
some refactoring.

By the way, pq_start/endcopyout() are used only in FE protocols
below 3.0, which had already bacome obsolete as of PG7.4. While
the next dev cycle is for PG10, if there is no particular reason
to support such acient protocols, removing them would make things
easier and cleaner.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Michael Paquier
michael.paquier@gmail.com
In reply to: Kyotaro HORIGUCHI (#5)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

On Fri, Jul 29, 2016 at 12:18 PM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

At Thu, 28 Jul 2016 10:46:00 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <4313.1469717160@sss.pgh.pa.us>

Fujii Masao <masao.fujii@gmail.com> writes:

3. Several source comments in pqcomm.c have not been updated.
Some comments still use the old function name like pq_putmessage().

Attached patch fixes the above issues.

I dunno, this seems like it's doubling down on some extremely poor
decisions. Why is it that you now have to flip a coin to guess whether
the prefix is pq_ or socket_ for functions in this module? I would
rather see that renaming reverted.

Yes, I agree with that. I cannot understand the intention behind
2bd9e41 to rename those routines as they are now, so getting them back
with pg_ as prefix looks like a good idea to me.

The set of functions in PQcommMethods doesn't seem clean. They
are chosen arbitrarily just so that other pq_* functions used in
parallel workers will work as expected. I suppose that it needs
some refactoring.

Any work in this area is likely 10.0 material at this point.

By the way, pq_start/endcopyout() are used only in FE protocols
below 3.0, which had already bacome obsolete as of PG7.4. While
the next dev cycle is for PG10, if there is no particular reason
to support such ancient protocols, removing them would make things
easier and cleaner.

Remove support for protocol 2 has been in the air for some time, but
that's a separate discussion. If you want to discuss this issue
particularly, raising a new thread would be a good idea.
--
Michael

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Kyotaro HORIGUCHI
horiguchi.kyotaro@lab.ntt.co.jp
In reply to: Michael Paquier (#6)
1 attachment(s)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

At Fri, 29 Jul 2016 12:47:53 +0900, Michael Paquier <michael.paquier@gmail.com> wrote in <CAB7nPqSSNTroRi=zGMDxYa7PzX_VSck6hbHY6eTnBBsfYaah6A@mail.gmail.com>

On Fri, Jul 29, 2016 at 12:18 PM, Kyotaro HORIGUCHI
<horiguchi.kyotaro@lab.ntt.co.jp> wrote:

At Thu, 28 Jul 2016 10:46:00 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <4313.1469717160@sss.pgh.pa.us>

Fujii Masao <masao.fujii@gmail.com> writes:

3. Several source comments in pqcomm.c have not been updated.
Some comments still use the old function name like pq_putmessage().

Attached patch fixes the above issues.

I dunno, this seems like it's doubling down on some extremely poor
decisions. Why is it that you now have to flip a coin to guess whether
the prefix is pq_ or socket_ for functions in this module? I would
rather see that renaming reverted.

Yes, I agree with that. I cannot understand the intention behind
2bd9e41 to rename those routines as they are now, so getting them back
with pg_ as prefix looks like a good idea to me.

The many of the socket_* functions are required to be replaced
with mq_* functions for backgroud workers. So reverting the names
of socket_* functions should be accompanied by the need to, for
example, changing their callers to use them explicitly via
PqCommMethods, not hiding with macros, or renaming current pq_*
macros to, say, pqi_. (it stands for PQ-Indirect as a tentative)
I'm not confident on the new prefix since I'm not sure that what
the 'pq' stands for. (Postgres Query?)

Attached patch is a rush work to revert the names of socket_
functions and replace the prefix of the macros with "pqi". pq_
names no longer points to mq_ functions. Is this roughly on the
right way? Even though the prefix is not appropriate.

The set of functions in PQcommMethods doesn't seem clean. They
are chosen arbitrarily just so that other pq_* functions used in
parallel workers will work as expected. I suppose that it needs
some refactoring.

Any work in this area is likely 10.0 material at this point.

By the way, pq_start/endcopyout() are used only in FE protocols
below 3.0, which had already bacome obsolete as of PG7.4. While
the next dev cycle is for PG10, if there is no particular reason
to support such ancient protocols, removing them would make things
easier and cleaner.

Remove support for protocol 2 has been in the air for some time, but
that's a separate discussion. If you want to discuss this issue
particularly, raising a new thread would be a good idea.

Thanks. I saw in somewhere that the protocol 2 no longer
works. I'll raise a new thread later.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

Attachments:

0001-Revert-socket_-functions-name-to-pq_-names.patchtext/x-patch; charset=us-asciiDownload
From b38b9a21d8cc73f3c20df46fb0db17db237c27ac Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Fri, 29 Jul 2016 14:45:15 +0900
Subject: [PATCH] Revert socket_ functions' name to pq_ names.

---
 src/backend/access/transam/parallel.c |  2 +-
 src/backend/commands/async.c          |  2 +-
 src/backend/commands/copy.c           | 12 ++---
 src/backend/libpq/auth.c              |  2 +-
 src/backend/libpq/pqcomm.c            | 84 +++++++++++++++++------------------
 src/backend/libpq/pqformat.c          |  8 ++--
 src/backend/replication/basebackup.c  | 14 +++---
 src/backend/replication/walsender.c   | 44 +++++++++---------
 src/backend/tcop/dest.c               |  6 +--
 src/backend/tcop/postgres.c           |  4 +-
 src/backend/utils/error/elog.c        |  4 +-
 src/include/libpq/libpq.h             | 16 +++----
 12 files changed, 99 insertions(+), 99 deletions(-)

diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index eef1dc2..1ab2921 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -1072,7 +1072,7 @@ ParallelWorkerMain(Datum main_arg)
 	EndParallelWorkerTransaction();
 
 	/* Report success. */
-	pq_putmessage('X', NULL, 0);
+	pqi_putmessage('X', NULL, 0);
 }
 
 /*
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 716f1c3..987c05e 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -2062,7 +2062,7 @@ ProcessIncomingNotify(void)
 	/*
 	 * Must flush the notify messages to ensure frontend gets them promptly.
 	 */
-	pq_flush();
+	pqi_flush();
 
 	set_ps_display("idle", false);
 
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index f45b330..a41eb00 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -362,7 +362,7 @@ SendCopyBegin(CopyState cstate)
 			errmsg("COPY BINARY is not supported to stdout or from stdin")));
 		pq_putemptymessage('H');
 		/* grottiness needed for old COPY OUT protocol */
-		pq_startcopyout();
+		pqi_startcopyout();
 		cstate->copy_dest = COPY_OLD_FE;
 	}
 	else
@@ -374,7 +374,7 @@ SendCopyBegin(CopyState cstate)
 			errmsg("COPY BINARY is not supported to stdout or from stdin")));
 		pq_putemptymessage('B');
 		/* grottiness needed for old COPY OUT protocol */
-		pq_startcopyout();
+		pqi_startcopyout();
 		cstate->copy_dest = COPY_OLD_FE;
 	}
 }
@@ -424,7 +424,7 @@ ReceiveCopyBegin(CopyState cstate)
 		cstate->copy_dest = COPY_OLD_FE;
 	}
 	/* We *must* flush here to ensure FE knows it can send. */
-	pq_flush();
+	pqi_flush();
 }
 
 static void
@@ -442,7 +442,7 @@ SendCopyEnd(CopyState cstate)
 		CopySendData(cstate, "\\.", 2);
 		/* Need to flush out the trailer (this also appends a newline) */
 		CopySendEndOfRow(cstate);
-		pq_endcopyout(false);
+		pqi_endcopyout(false);
 	}
 }
 
@@ -544,7 +544,7 @@ CopySendEndOfRow(CopyState cstate)
 				CopySendChar(cstate, '\n');
 
 			/* Dump the accumulated row as one CopyData message */
-			(void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len);
+			(void) pqi_putmessage('d', fe_msgbuf->data, fe_msgbuf->len);
 			break;
 	}
 
@@ -1818,7 +1818,7 @@ DoCopyTo(CopyState cstate)
 		 * okay to do this in all cases, since it does nothing if the mode is
 		 * not on.
 		 */
-		pq_endcopyout(true);
+		pqi_endcopyout(true);
 		PG_RE_THROW();
 	}
 	PG_END_TRY();
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 7d8fc3e..a274303 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -631,7 +631,7 @@ sendAuthRequest(Port *port, AuthRequest areq)
 	 * not be sent until we are ready for queries.
 	 */
 	if (areq != AUTH_REQ_OK)
-		pq_flush();
+		pqi_flush();
 
 	CHECK_FOR_INTERRUPTS();
 }
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index ba42753..4b5a198 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -133,16 +133,16 @@ static bool DoingCopyOut;		/* in old-protocol COPY OUT processing */
 
 
 /* Internal functions */
-static void socket_comm_reset(void);
-static void socket_close(int code, Datum arg);
-static void socket_set_nonblocking(bool nonblocking);
-static int	socket_flush(void);
-static int	socket_flush_if_writable(void);
-static bool socket_is_send_pending(void);
-static int	socket_putmessage(char msgtype, const char *s, size_t len);
-static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
-static void socket_startcopyout(void);
-static void socket_endcopyout(bool errorAbort);
+static void pq_comm_reset(void);
+static void pq_close(int code, Datum arg);
+static void pq_set_nonblocking(bool nonblocking);
+static int	pq_flush(void);
+static int	pq_flush_if_writable(void);
+static bool pq_is_send_pending(void);
+static int	pq_putmessage(char msgtype, const char *s, size_t len);
+static void pq_putmessage_noblock(char msgtype, const char *s, size_t len);
+static void pq_startcopyout(void);
+static void pq_endcopyout(bool errorAbort);
 static int	internal_putbytes(const char *s, size_t len);
 static int	internal_flush(void);
 static void socket_set_nonblocking(bool nonblocking);
@@ -153,14 +153,14 @@ static int	Setup_AF_UNIX(char *sock_path);
 #endif   /* HAVE_UNIX_SOCKETS */
 
 static PQcommMethods PqCommSocketMethods = {
-	socket_comm_reset,
-	socket_flush,
-	socket_flush_if_writable,
-	socket_is_send_pending,
-	socket_putmessage,
-	socket_putmessage_noblock,
-	socket_startcopyout,
-	socket_endcopyout
+	pq_comm_reset,
+	pq_flush,
+	pq_flush_if_writable,
+	pq_is_send_pending,
+	pq_putmessage,
+	pq_putmessage_noblock,
+	pq_startcopyout,
+	pq_endcopyout
 };
 
 PQcommMethods *PqCommMethods = &PqCommSocketMethods;
@@ -184,7 +184,7 @@ pq_init(void)
 	DoingCopyOut = false;
 
 	/* set up process-exit hook to close the socket */
-	on_proc_exit(socket_close, 0);
+	on_proc_exit(pq_close, 0);
 
 	/*
 	 * In backends (as soon as forked) we operate the underlying socket in
@@ -210,7 +210,7 @@ pq_init(void)
 }
 
 /* --------------------------------
- *		socket_comm_reset - reset libpq during error recovery
+ *		pq_comm_reset - reset libpq during error recovery
  *
  * This is called from error recovery at the outer idle loop.  It's
  * just to get us out of trouble if we somehow manage to elog() from
@@ -218,7 +218,7 @@ pq_init(void)
  * --------------------------------
  */
 static void
-socket_comm_reset(void)
+pq_comm_reset(void)
 {
 	/* Do not throw away pending data, but do reset the busy flag */
 	PqCommBusy = false;
@@ -227,7 +227,7 @@ socket_comm_reset(void)
 }
 
 /* --------------------------------
- *		socket_close - shutdown libpq at backend exit
+ *		pq_close - shutdown libpq at backend exit
  *
  * This is the one pg_on_exit_callback in place during BackendInitialize().
  * That function's unusual signal handling constrains that this callback be
@@ -235,7 +235,7 @@ socket_comm_reset(void)
  * --------------------------------
  */
 static void
-socket_close(int code, Datum arg)
+pq_close(int code, Datum arg)
 {
 	/* Nothing to do in a standalone backend, where MyProcPort is NULL. */
 	if (MyProcPort != NULL)
@@ -870,14 +870,14 @@ RemoveSocketFiles(void)
  */
 
 /* --------------------------------
- *			  socket_set_nonblocking - set socket blocking/non-blocking
+ *			  pq_set_nonblocking - set socket blocking/non-blocking
  *
  * Sets the socket non-blocking if nonblocking is TRUE, or sets it
  * blocking otherwise.
  * --------------------------------
  */
 static void
-socket_set_nonblocking(bool nonblocking)
+pq_set_nonblocking(bool nonblocking)
 {
 	if (MyProcPort == NULL)
 		ereport(ERROR,
@@ -911,7 +911,7 @@ pq_recvbuf(void)
 	}
 
 	/* Ensure that we're in blocking mode */
-	socket_set_nonblocking(false);
+	pq_set_nonblocking(false);
 
 	/* Can fill buffer from PqRecvLength and upwards */
 	for (;;)
@@ -1008,7 +1008,7 @@ pq_getbyte_if_available(unsigned char *c)
 	}
 
 	/* Put the socket into non-blocking mode */
-	socket_set_nonblocking(true);
+	pq_set_nonblocking(true);
 
 	r = secure_read(MyProcPort, c, 1);
 	if (r < 0)
@@ -1333,7 +1333,7 @@ internal_putbytes(const char *s, size_t len)
 		/* If buffer is full, then flush it out */
 		if (PqSendPointer >= PqSendBufferSize)
 		{
-			socket_set_nonblocking(false);
+			pq_set_nonblocking(false);
 			if (internal_flush())
 				return EOF;
 		}
@@ -1349,13 +1349,13 @@ internal_putbytes(const char *s, size_t len)
 }
 
 /* --------------------------------
- *		socket_flush		- flush pending output
+ *		pq_flush		- flush pending output
  *
  *		returns 0 if OK, EOF if trouble
  * --------------------------------
  */
 static int
-socket_flush(void)
+pq_flush(void)
 {
 	int			res;
 
@@ -1363,7 +1363,7 @@ socket_flush(void)
 	if (PqCommBusy)
 		return 0;
 	PqCommBusy = true;
-	socket_set_nonblocking(false);
+	pq_set_nonblocking(false);
 	res = internal_flush();
 	PqCommBusy = false;
 	return res;
@@ -1450,7 +1450,7 @@ internal_flush(void)
  * --------------------------------
  */
 static int
-socket_flush_if_writable(void)
+pq_flush_if_writable(void)
 {
 	int			res;
 
@@ -1463,7 +1463,7 @@ socket_flush_if_writable(void)
 		return 0;
 
 	/* Temporarily put the socket into non-blocking mode */
-	socket_set_nonblocking(true);
+	pq_set_nonblocking(true);
 
 	PqCommBusy = true;
 	res = internal_flush();
@@ -1472,11 +1472,11 @@ socket_flush_if_writable(void)
 }
 
 /* --------------------------------
- *	socket_is_send_pending	- is there any pending data in the output buffer?
+ *		pq_is_send_pending	- is there any pending data in the output buffer?
  * --------------------------------
  */
 static bool
-socket_is_send_pending(void)
+pq_is_send_pending(void)
 {
 	return (PqSendStart < PqSendPointer);
 }
@@ -1490,7 +1490,7 @@ socket_is_send_pending(void)
 
 
 /* --------------------------------
- *		socket_putmessage - send a normal message (suppressed in COPY OUT mode)
+ *		pq_putmessage	- send a normal message (suppressed in COPY OUT mode)
  *
  *		If msgtype is not '\0', it is a message type code to place before
  *		the message body.  If msgtype is '\0', then the message has no type
@@ -1515,7 +1515,7 @@ socket_is_send_pending(void)
  * --------------------------------
  */
 static int
-socket_putmessage(char msgtype, const char *s, size_t len)
+pq_putmessage(char msgtype, const char *s, size_t len)
 {
 	if (DoingCopyOut || PqCommBusy)
 		return 0;
@@ -1548,7 +1548,7 @@ fail:
  *		is enlarged.
  */
 static void
-socket_putmessage_noblock(char msgtype, const char *s, size_t len)
+pq_putmessage_noblock(char msgtype, const char *s, size_t len)
 {
 	int res		PG_USED_FOR_ASSERTS_ONLY;
 	int			required;
@@ -1570,18 +1570,18 @@ socket_putmessage_noblock(char msgtype, const char *s, size_t len)
 
 
 /* --------------------------------
- *		socket_startcopyout - inform libpq that an old-style COPY OUT transfer
+ *		pq_startcopyout - inform libpq that an old-style COPY OUT transfer
  *			is beginning
  * --------------------------------
  */
 static void
-socket_startcopyout(void)
+pq_startcopyout(void)
 {
 	DoingCopyOut = true;
 }
 
 /* --------------------------------
- *		socket_endcopyout	- end an old-style COPY OUT transfer
+ *		pq_endcopyout	- end an old-style COPY OUT transfer
  *
  *		If errorAbort is indicated, we are aborting a COPY OUT due to an error,
  *		and must send a terminator line.  Since a partial data line might have
@@ -1591,7 +1591,7 @@ socket_startcopyout(void)
  * --------------------------------
  */
 static void
-socket_endcopyout(bool errorAbort)
+pq_endcopyout(bool errorAbort)
 {
 	if (!DoingCopyOut)
 		return;
diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c
index b5d9d64..581370e 100644
--- a/src/backend/libpq/pqformat.c
+++ b/src/backend/libpq/pqformat.c
@@ -344,7 +344,7 @@ void
 pq_endmessage(StringInfo buf)
 {
 	/* msgtype was saved in cursor field */
-	(void) pq_putmessage(buf->cursor, buf->data, buf->len);
+	(void) pqi_putmessage(buf->cursor, buf->data, buf->len);
 	/* no need to complain about any failure, since pqcomm.c already did */
 	pfree(buf->data);
 	buf->data = NULL;
@@ -405,11 +405,11 @@ pq_puttextmessage(char msgtype, const char *str)
 	p = pg_server_to_client(str, slen);
 	if (p != str)				/* actual conversion has been done? */
 	{
-		(void) pq_putmessage(msgtype, p, strlen(p) + 1);
+		(void) pqi_putmessage(msgtype, p, strlen(p) + 1);
 		pfree(p);
 		return;
 	}
-	(void) pq_putmessage(msgtype, str, slen + 1);
+	(void) pqi_putmessage(msgtype, str, slen + 1);
 }
 
 
@@ -420,7 +420,7 @@ pq_puttextmessage(char msgtype, const char *str)
 void
 pq_putemptymessage(char msgtype)
 {
-	(void) pq_putmessage(msgtype, NULL, 0);
+	(void) pqi_putmessage(msgtype, NULL, 0);
 }
 
 
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index da9b7a6..1fa713b 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -421,7 +421,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
 			{
 				CheckXLogRemoved(segno, tli);
 				/* Send the chunk as a CopyData message */
-				if (pq_putmessage('d', buf, cnt))
+				if (pqi_putmessage('d', buf, cnt))
 					ereport(ERROR,
 							(errmsg("base backup could not send data, aborting backup")));
 
@@ -809,7 +809,7 @@ sendFileWithContent(const char *filename, const char *content)
 
 	_tarWriteHeader(filename, NULL, &statbuf);
 	/* Send the contents as a CopyData message */
-	pq_putmessage('d', content, len);
+	pqi_putmessage('d', content, len);
 
 	/* Pad to 512 byte boundary, per tar format requirements */
 	pad = ((len + 511) & ~511) - len;
@@ -818,7 +818,7 @@ sendFileWithContent(const char *filename, const char *content)
 		char		buf[512];
 
 		MemSet(buf, 0, pad);
-		pq_putmessage('d', buf, pad);
+		pqi_putmessage('d', buf, pad);
 	}
 }
 
@@ -1167,7 +1167,7 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf,
 	while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0)
 	{
 		/* Send the chunk as a CopyData message */
-		if (pq_putmessage('d', buf, cnt))
+		if (pqi_putmessage('d', buf, cnt))
 			ereport(ERROR,
 			   (errmsg("base backup could not send data, aborting backup")));
 
@@ -1192,7 +1192,7 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf,
 		while (len < statbuf->st_size)
 		{
 			cnt = Min(sizeof(buf), statbuf->st_size - len);
-			pq_putmessage('d', buf, cnt);
+			pqi_putmessage('d', buf, cnt);
 			len += cnt;
 			throttle(cnt);
 		}
@@ -1206,7 +1206,7 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf,
 	if (pad > 0)
 	{
 		MemSet(buf, 0, pad);
-		pq_putmessage('d', buf, pad);
+		pqi_putmessage('d', buf, pad);
 	}
 
 	FreeFile(fp);
@@ -1244,7 +1244,7 @@ _tarWriteHeader(const char *filename, const char *linktarget,
 			elog(ERROR, "unrecognized tar error: %d", rc);
 	}
 
-	pq_putmessage('d', h, 512);
+	pqi_putmessage('d', h, 512);
 }
 
 /*
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index a0dba19..4baf723 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -636,7 +636,7 @@ StartReplication(StartReplicationCmd *cmd)
 		pq_sendbyte(&buf, 0);
 		pq_sendint(&buf, 0, 2);
 		pq_endmessage(&buf);
-		pq_flush();
+		pqi_flush();
 
 		/*
 		 * Don't allow a request to stream from a future point in WAL that
@@ -982,7 +982,7 @@ StartLogicalReplication(StartReplicationCmd *cmd)
 	pq_sendbyte(&buf, 0);
 	pq_sendint(&buf, 0, 2);
 	pq_endmessage(&buf);
-	pq_flush();
+	pqi_flush();
 
 	/* setup state for XLogReadPage */
 	sendTimeLineIsHistoric = false;
@@ -1074,7 +1074,7 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
 				bool last_write)
 {
 	/* output previously gathered data in a CopyData packet */
-	pq_putmessage_noblock('d', ctx->out->data, ctx->out->len);
+	pqi_putmessage_noblock('d', ctx->out->data, ctx->out->len);
 
 	/*
 	 * Fill the send timestamp last, so that it is taken as late as possible.
@@ -1088,10 +1088,10 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
 
 	/* fast path */
 	/* Try to flush pending output to the client */
-	if (pq_flush_if_writable() != 0)
+	if (pqi_flush_if_writable() != 0)
 		WalSndShutdown();
 
-	if (!pq_is_send_pending())
+	if (!pqi_is_send_pending())
 		return;
 
 	for (;;)
@@ -1124,11 +1124,11 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
 		ProcessRepliesIfAny();
 
 		/* Try to flush pending output to the client */
-		if (pq_flush_if_writable() != 0)
+		if (pqi_flush_if_writable() != 0)
 			WalSndShutdown();
 
 		/* If we finished clearing the buffered data, we're done here. */
-		if (!pq_is_send_pending())
+		if (!pqi_is_send_pending())
 			break;
 
 		now = GetCurrentTimestamp();
@@ -1251,7 +1251,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 		 * to flush. Otherwise we might just sit on output data while waiting
 		 * for new WAL being generated.
 		 */
-		if (pq_flush_if_writable() != 0)
+		if (pqi_flush_if_writable() != 0)
 			WalSndShutdown();
 
 		now = GetCurrentTimestamp();
@@ -1267,7 +1267,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 		wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH |
 			WL_SOCKET_READABLE | WL_TIMEOUT;
 
-		if (pq_is_send_pending())
+		if (pqi_is_send_pending())
 			wakeEvents |= WL_SOCKET_WRITEABLE;
 
 		/* Sleep until something happens or we time out */
@@ -1441,7 +1441,7 @@ ProcessRepliesIfAny(void)
 			case 'c':
 				if (!streamingDoneSending)
 				{
-					pq_putmessage_noblock('c', NULL, 0);
+					pqi_putmessage_noblock('c', NULL, 0);
 					streamingDoneSending = true;
 				}
 
@@ -1844,7 +1844,7 @@ WalSndLoop(WalSndSendDataCallback send_data)
 		 * ourselves, and the output buffer is empty, it's time to exit
 		 * streaming.
 		 */
-		if (!pq_is_send_pending() && streamingDoneSending && streamingDoneReceiving)
+		if (!pqi_is_send_pending() && streamingDoneSending && streamingDoneReceiving)
 			break;
 
 		/*
@@ -1853,17 +1853,17 @@ WalSndLoop(WalSndSendDataCallback send_data)
 		 * again until we've flushed it ... but we'd better assume we are not
 		 * caught up.
 		 */
-		if (!pq_is_send_pending())
+		if (!pqi_is_send_pending())
 			send_data();
 		else
 			WalSndCaughtUp = false;
 
 		/* Try to flush pending output to the client */
-		if (pq_flush_if_writable() != 0)
+		if (pqi_flush_if_writable() != 0)
 			WalSndShutdown();
 
 		/* If nothing remains to be sent right now ... */
-		if (WalSndCaughtUp && !pq_is_send_pending())
+		if (WalSndCaughtUp && !pqi_is_send_pending())
 		{
 			/*
 			 * If we're in catchup state, move to streaming.  This is an
@@ -1908,7 +1908,7 @@ WalSndLoop(WalSndSendDataCallback send_data)
 		 * pq_flush_if_writable flushed it all --- we should immediately try
 		 * to send more.
 		 */
-		if ((WalSndCaughtUp && !streamingDoneSending) || pq_is_send_pending())
+		if ((WalSndCaughtUp && !streamingDoneSending) || pqi_is_send_pending())
 		{
 			long		sleeptime;
 			int			wakeEvents;
@@ -1918,7 +1918,7 @@ WalSndLoop(WalSndSendDataCallback send_data)
 
 			sleeptime = WalSndComputeSleeptime(now);
 
-			if (pq_is_send_pending())
+			if (pqi_is_send_pending())
 				wakeEvents |= WL_SOCKET_WRITEABLE;
 
 			/* Sleep until something happens or we time out */
@@ -2313,7 +2313,7 @@ XLogSendPhysical(void)
 		sendFile = -1;
 
 		/* Send CopyDone */
-		pq_putmessage_noblock('c', NULL, 0);
+		pqi_putmessage_noblock('c', NULL, 0);
 		streamingDoneSending = true;
 
 		WalSndCaughtUp = true;
@@ -2393,7 +2393,7 @@ XLogSendPhysical(void)
 	memcpy(&output_message.data[1 + sizeof(int64) + sizeof(int64)],
 		   tmpbuf.data, sizeof(int64));
 
-	pq_putmessage_noblock('d', output_message.data, output_message.len);
+	pqi_putmessage_noblock('d', output_message.data, output_message.len);
 
 	sentPtr = endptr;
 
@@ -2496,11 +2496,11 @@ WalSndDone(WalSndSendDataCallback send_data)
 		MyWalSnd->write : MyWalSnd->flush;
 
 	if (WalSndCaughtUp && sentPtr == replicatedPtr &&
-		!pq_is_send_pending())
+		!pqi_is_send_pending())
 	{
 		/* Inform the standby that XLOG streaming is done */
 		EndCommand("COPY 0", DestRemote);
-		pq_flush();
+		pqi_flush();
 
 		proc_exit(0);
 	}
@@ -2893,7 +2893,7 @@ WalSndKeepalive(bool requestReply)
 	pq_sendbyte(&output_message, requestReply ? 1 : 0);
 
 	/* ... and send it wrapped in CopyData */
-	pq_putmessage_noblock('d', output_message.data, output_message.len);
+	pqi_putmessage_noblock('d', output_message.data, output_message.len);
 }
 
 /*
@@ -2927,7 +2927,7 @@ WalSndKeepaliveIfNecessary(TimestampTz now)
 		waiting_for_ping_response = true;
 
 		/* Try to flush pending output to the client */
-		if (pq_flush_if_writable() != 0)
+		if (pqi_flush_if_writable() != 0)
 			WalSndShutdown();
 	}
 }
diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c
index de45cbc..af5449e 100644
--- a/src/backend/tcop/dest.c
+++ b/src/backend/tcop/dest.c
@@ -156,7 +156,7 @@ EndCommand(const char *commandTag, CommandDest dest)
 			 * We assume the commandTag is plain ASCII and therefore requires
 			 * no encoding conversion.
 			 */
-			pq_putmessage('C', commandTag, strlen(commandTag) + 1);
+			pqi_putmessage('C', commandTag, strlen(commandTag) + 1);
 			break;
 
 		case DestNone:
@@ -199,7 +199,7 @@ NullCommand(CommandDest dest)
 			if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
 				pq_putemptymessage('I');
 			else
-				pq_putmessage('I', "", 1);
+				pqi_putmessage('I', "", 1);
 			break;
 
 		case DestNone:
@@ -244,7 +244,7 @@ ReadyForQuery(CommandDest dest)
 			else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
 				pq_putemptymessage('Z');
 			/* Flush output at end of cycle in any case. */
-			pq_flush();
+			pqi_flush();
 			break;
 
 		case DestNone:
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index b185c1b..cb1f8e4 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3860,7 +3860,7 @@ PostgresMain(int argc, char *argv[],
 		DoingCommandRead = false;
 
 		/* Make sure libpq is in a good state */
-		pq_comm_reset();
+		pqi_comm_reset();
 
 		/* Report the error to the client and/or server log */
 		EmitErrorReport();
@@ -4262,7 +4262,7 @@ PostgresMain(int argc, char *argv[],
 			case 'H':			/* flush */
 				pq_getmsgend(&input_message);
 				if (whereToSendOutput == DestRemote)
-					pq_flush();
+					pqi_flush();
 				break;
 
 			case 'S':			/* sync */
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 78d441d..a0dc841 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -477,7 +477,7 @@ errfinish(int dummy,...)
 	 * client_min_messages above FATAL, so don't look at output_to_client.
 	 */
 	if (elevel >= FATAL && whereToSendOutput == DestRemote)
-		pq_endcopyout(true);
+		pqi_endcopyout(true);
 
 	/* Emit the message to the right places */
 	EmitErrorReport();
@@ -3302,7 +3302,7 @@ send_message_to_frontend(ErrorData *edata)
 	 * messages should not be a performance-critical path anyway, so an extra
 	 * flush won't hurt much ...
 	 */
-	pq_flush();
+	pqi_flush();
 }
 
 
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 547d3b8..79041a8 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -36,16 +36,16 @@ typedef struct
 
 extern PGDLLIMPORT PQcommMethods *PqCommMethods;
 
-#define pq_comm_reset() (PqCommMethods->comm_reset())
-#define pq_flush() (PqCommMethods->flush())
-#define pq_flush_if_writable() (PqCommMethods->flush_if_writable())
-#define pq_is_send_pending() (PqCommMethods->is_send_pending())
-#define pq_putmessage(msgtype, s, len) \
+#define pqi_comm_reset() (PqCommMethods->comm_reset())
+#define pqi_flush() (PqCommMethods->flush())
+#define pqi_flush_if_writable() (PqCommMethods->flush_if_writable())
+#define pqi_is_send_pending() (PqCommMethods->is_send_pending())
+#define pqi_putmessage(msgtype, s, len) \
 	(PqCommMethods->putmessage(msgtype, s, len))
-#define pq_putmessage_noblock(msgtype, s, len) \
+#define pqi_putmessage_noblock(msgtype, s, len) \
 	(PqCommMethods->putmessage(msgtype, s, len))
-#define pq_startcopyout() (PqCommMethods->startcopyout())
-#define pq_endcopyout(errorAbort) (PqCommMethods->endcopyout(errorAbort))
+#define pqi_startcopyout() (PqCommMethods->startcopyout())
+#define pqi_endcopyout(errorAbort) (PqCommMethods->endcopyout(errorAbort))
 
 /*
  * External functions.
-- 
1.8.3.1

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Kyotaro HORIGUCHI (#7)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> writes:

At Fri, 29 Jul 2016 12:47:53 +0900, Michael Paquier <michael.paquier@gmail.com> wrote in <CAB7nPqSSNTroRi=zGMDxYa7PzX_VSck6hbHY6eTnBBsfYaah6A@mail.gmail.com>

At Thu, 28 Jul 2016 10:46:00 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <4313.1469717160@sss.pgh.pa.us>
I dunno, this seems like it's doubling down on some extremely poor
decisions. Why is it that you now have to flip a coin to guess whether
the prefix is pq_ or socket_ for functions in this module? I would
rather see that renaming reverted.

Yes, I agree with that. I cannot understand the intention behind
2bd9e41 to rename those routines as they are now, so getting them back
with pg_ as prefix looks like a good idea to me.

The many of the socket_* functions are required to be replaced
with mq_* functions for backgroud workers. So reverting the names
of socket_* functions should be accompanied by the need to, for
example, changing their callers to use them explicitly via
PqCommMethods, not hiding with macros, or renaming current pq_*
macros to, say, pqi_. (it stands for PQ-Indirect as a tentative)
I'm not confident on the new prefix since I'm not sure that what
the 'pq' stands for. (Postgres Query?)

Hmm. Of course the problem with this approach is that we end up touching
a whole bunch of call sites, which sort of negates the point of having
installed a compatibility macro layer.

[ spends awhile longer looking around at this code ]

Maybe the real problem here is that the abstraction layer is so incomplete
and apparently haphazard, so that it's not very obvious where you should
use a pq_xxx name and where you should refer to socket_xxx. For some of
the functions in pqcomm.c, such as internal_flush, it's impossible to tell
which side of the abstraction boundary they're supposed to be on.
(I suspect that that particular function has simply been ignored on the
undocumented assumption that a bgworker could never call it, but that's
the kind of half-baked work that I don't find acceptable.)

I think the core work that needs to be done here is to clearly identify
each function in pqcomm.c as either above or below the PqCommMethods
abstraction boundary. Maybe we should split one set or the other out
to a new source file. In any case, the naming convention ought to
reflect that hierarchy.

I withdraw the idea that we should try to revert all these functions back
to their old names, since that would obscure the layering distinction
between socket-specific and general-usage functions. I now think that
the problem is that that distinction hasn't been drawn sharply enough.

The set of functions in PQcommMethods doesn't seem clean. They
are chosen arbitrarily just so that other pq_* functions used in
parallel workers will work as expected. I suppose that it needs
some refactoring.

Yeah, exactly.

Any work in this area is likely 10.0 material at this point.

I'm not really happy with that, since refactoring it again will create
back-patch hazards. But I see that a lot of the mess here was created
in 9.5, which means we're probably stuck with back-patch hazards anyway.

regards, tom lane

PS: "PQ" comes from PostQUEL, I believe.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#8)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

I wrote:

Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> writes:

Any work in this area is likely 10.0 material at this point.

I'm not really happy with that, since refactoring it again will create
back-patch hazards. But I see that a lot of the mess here was created
in 9.5, which means we're probably stuck with back-patch hazards anyway.

I've pushed Kyotaro-san's original patch, which is clearly a bug fix.
I think the additional changes discussed later in this thread are
cosmetic, and probably should wait for a more general review of the
layering decisions in pqcomm.c.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Kyotaro HORIGUCHI
horiguchi.kyotaro@lab.ntt.co.jp
In reply to: Tom Lane (#9)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

At Fri, 29 Jul 2016 13:00:50 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <29430.1469811650@sss.pgh.pa.us>

I wrote:

Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> writes:

Any work in this area is likely 10.0 material at this point.

I'm not really happy with that, since refactoring it again will create
back-patch hazards. But I see that a lot of the mess here was created
in 9.5, which means we're probably stuck with back-patch hazards anyway.

I've pushed Kyotaro-san's original patch, which is clearly a bug fix.
I think the additional changes discussed later in this thread are
cosmetic, and probably should wait for a more general review of the
layering decisions in pqcomm.c.

Agreed. It's not an abstraction or API, but it actually works
with no problem and changing it is an issue obviously for later
discussion.

Anyway thank you for committing this.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Kyotaro HORIGUCHI
horiguchi.kyotaro@lab.ntt.co.jp
In reply to: Tom Lane (#8)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

At Fri, 29 Jul 2016 11:58:04 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in <14846.1469807884@sss.pgh.pa.us>

Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp> writes:

The many of the socket_* functions are required to be replaced
with mq_* functions for backgroud workers. So reverting the names
of socket_* functions should be accompanied by the need to, for
example, changing their callers to use them explicitly via
PqCommMethods, not hiding with macros, or renaming current pq_*
macros to, say, pqi_. (it stands for PQ-Indirect as a tentative)
I'm not confident on the new prefix since I'm not sure that what
the 'pq' stands for. (Postgres Query?)

Hmm. Of course the problem with this approach is that we end up touching
a whole bunch of call sites, which sort of negates the point of having
installed a compatibility macro layer.

[ spends awhile longer looking around at this code ]

Maybe the real problem here is that the abstraction layer is so incomplete
and apparently haphazard, so that it's not very obvious where you should
use a pq_xxx name and where you should refer to socket_xxx.

Yes, 'haphazard' is the word I was seeking for.

For some of
the functions in pqcomm.c, such as internal_flush, it's impossible to tell
which side of the abstraction boundary they're supposed to be on.
(I suspect that that particular function has simply been ignored on the
undocumented assumption that a bgworker could never call it, but that's
the kind of half-baked work that I don't find acceptable.)

I think the core work that needs to be done here is to clearly identify
each function in pqcomm.c as either above or below the PqCommMethods
abstraction boundary. Maybe we should split one set or the other out
to a new source file. In any case, the naming convention ought to
reflect that hierarchy.

Agreed. I'm not sure if there's a clean boundary, though.

I withdraw the idea that we should try to revert all these functions back
to their old names, since that would obscure the layering distinction
between socket-specific and general-usage functions. I now think that
the problem is that that distinction hasn't been drawn sharply enough.

The set of functions in PQcommMethods doesn't seem clean. They
are chosen arbitrarily just so that other pq_* functions used in
parallel workers will work as expected. I suppose that it needs
some refactoring.

Yeah, exactly.

Any work in this area is likely 10.0 material at this point.

I'm not really happy with that, since refactoring it again will create
back-patch hazards. But I see that a lot of the mess here was created
in 9.5, which means we're probably stuck with back-patch hazards anyway.

I think we have an alternative not to backpatch that
refactoring. 9.5 works with it happily and won't get further
improovement in this area.

regards, tom lane

PS: "PQ" comes from PostQUEL, I believe.

Thanks, I've learned something new:)

https://en.wikipedia.org/wiki/QUEL_query_languages

range of E is EMPLOYEE
retrieve into W
(COMP = E.Salary / (E.Age - 18))
where E.Name = "Jones"

It looks more methematical or programming-language-like to me
than SQL.

regards,

--
Kyotaro Horiguchi
NTT Open Source Software Center

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#8)
Re: Wrong defeinition of pq_putmessage_noblock since 9.5

On Fri, Jul 29, 2016 at 11:58 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Maybe the real problem here is that the abstraction layer is so incomplete
and apparently haphazard, so that it's not very obvious where you should
use a pq_xxx name and where you should refer to socket_xxx. For some of
the functions in pqcomm.c, such as internal_flush, it's impossible to tell
which side of the abstraction boundary they're supposed to be on.
(I suspect that that particular function has simply been ignored on the
undocumented assumption that a bgworker could never call it, but that's
the kind of half-baked work that I don't find acceptable.)

I think the core work that needs to be done here is to clearly identify
each function in pqcomm.c as either above or below the PqCommMethods
abstraction boundary. Maybe we should split one set or the other out
to a new source file. In any case, the naming convention ought to
reflect that hierarchy.

I withdraw the idea that we should try to revert all these functions back
to their old names, since that would obscure the layering distinction
between socket-specific and general-usage functions. I now think that
the problem is that that distinction hasn't been drawn sharply enough.

If memory serves, there was some discussion of this at the time the
patch that changed this was originally submitted. The original patch,
IIRC, just installed one or two hooks and it was argued that I should
instead create some kind of abstraction layer. The present coding is
the result of my attempt to do just that. I have to admit that I
wasn't very eager to churn the contents of this file more than
necessary. It seems like old, crufty code to me. I don't object if
you want to refactor it, but I'm not sure what problem it solves.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers