mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	Implement pipeline mode in libpq
Pipeline mode in libpq lets an application avoid the Sync messages in the FE/BE protocol that are implicit in the old libpq API after each query. The application can then insert Sync at its leisure with a new libpq function PQpipelineSync. This can lead to substantial reductions in query latency. Co-authored-by: Craig Ringer <craig.ringer@enterprisedb.com> Co-authored-by: Matthieu Garrigues <matthieu.garrigues@gmail.com> Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Aya Iwata <iwata.aya@jp.fujitsu.com> Reviewed-by: Daniel Vérité <daniel@manitou-mail.org> Reviewed-by: David G. Johnston <david.g.johnston@gmail.com> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Reviewed-by: Kirk Jamison <k.jamison@fujitsu.com> Reviewed-by: Michael Paquier <michael.paquier@gmail.com> Reviewed-by: Nikhil Sontakke <nikhils@2ndquadrant.com> Reviewed-by: Vaishnavi Prabakaran <VaishnaviP@fast.au.fujitsu.com> Reviewed-by: Zhihong Yu <zyu@yugabyte.com> Discussion: https://postgr.es/m/CAMsr+YFUjJytRyV4J-16bEoiZyH=4nj+sQ7JP9ajwz=B4dMMZw@mail.gmail.com Discussion: https://postgr.es/m/CAJkzx4T5E-2cQe3dtv2R78dYFvz+in8PY7A8MArvLhs_pg75gg@mail.gmail.com
This commit is contained in:
		| @@ -217,21 +217,16 @@ typedef enum | ||||
| { | ||||
| 	PGASYNC_IDLE,				/* nothing's happening, dude */ | ||||
| 	PGASYNC_BUSY,				/* query in progress */ | ||||
| 	PGASYNC_READY,				/* result ready for PQgetResult */ | ||||
| 	PGASYNC_READY,				/* query done, waiting for client to fetch | ||||
| 								 * result */ | ||||
| 	PGASYNC_READY_MORE,			/* query done, waiting for client to fetch | ||||
| 								 * result, more results expected from this | ||||
| 								 * query */ | ||||
| 	PGASYNC_COPY_IN,			/* Copy In data transfer in progress */ | ||||
| 	PGASYNC_COPY_OUT,			/* Copy Out data transfer in progress */ | ||||
| 	PGASYNC_COPY_BOTH			/* Copy In/Out data transfer in progress */ | ||||
| } PGAsyncStatusType; | ||||
|  | ||||
| /* PGQueryClass tracks which query protocol we are now executing */ | ||||
| typedef enum | ||||
| { | ||||
| 	PGQUERY_SIMPLE,				/* simple Query protocol (PQexec) */ | ||||
| 	PGQUERY_EXTENDED,			/* full Extended protocol (PQexecParams) */ | ||||
| 	PGQUERY_PREPARE,			/* Parse only (PQprepare) */ | ||||
| 	PGQUERY_DESCRIBE			/* Describe Statement or Portal */ | ||||
| } PGQueryClass; | ||||
|  | ||||
| /* Target server type (decoded value of target_session_attrs) */ | ||||
| typedef enum | ||||
| { | ||||
| @@ -305,6 +300,29 @@ typedef enum pg_conn_host_type | ||||
| 	CHT_UNIX_SOCKET | ||||
| } pg_conn_host_type; | ||||
|  | ||||
| /* | ||||
|  * PGQueryClass tracks which query protocol is in use for each command queue | ||||
|  * entry, or special operation in execution | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
| 	PGQUERY_SIMPLE,				/* simple Query protocol (PQexec) */ | ||||
| 	PGQUERY_EXTENDED,			/* full Extended protocol (PQexecParams) */ | ||||
| 	PGQUERY_PREPARE,			/* Parse only (PQprepare) */ | ||||
| 	PGQUERY_DESCRIBE,			/* Describe Statement or Portal */ | ||||
| 	PGQUERY_SYNC				/* Sync (at end of a pipeline) */ | ||||
| } PGQueryClass; | ||||
|  | ||||
| /* | ||||
|  * An entry in the pending command queue. | ||||
|  */ | ||||
| typedef struct PGcmdQueueEntry | ||||
| { | ||||
| 	PGQueryClass queryclass;	/* Query type */ | ||||
| 	char	   *query;			/* SQL command, or NULL if none/unknown/OOM */ | ||||
| 	struct PGcmdQueueEntry *next;	/* list link */ | ||||
| } PGcmdQueueEntry; | ||||
|  | ||||
| /* | ||||
|  * pg_conn_host stores all information about each of possibly several hosts | ||||
|  * mentioned in the connection string.  Most fields are derived by splitting | ||||
| @@ -389,12 +407,11 @@ struct pg_conn | ||||
| 	ConnStatusType status; | ||||
| 	PGAsyncStatusType asyncStatus; | ||||
| 	PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ | ||||
| 	PGQueryClass queryclass; | ||||
| 	char	   *last_query;		/* last SQL command, or NULL if unknown */ | ||||
| 	char		last_sqlstate[6];	/* last reported SQLSTATE */ | ||||
| 	bool		options_valid;	/* true if OK to attempt connection */ | ||||
| 	bool		nonblocking;	/* whether this connection is using nonblock | ||||
| 								 * sending semantics */ | ||||
| 	PGpipelineStatus pipelineStatus;	/* status of pipeline mode */ | ||||
| 	bool		singleRowMode;	/* return current query result row-by-row? */ | ||||
| 	char		copy_is_binary; /* 1 = copy binary, 0 = copy text */ | ||||
| 	int			copy_already_done;	/* # bytes already returned in COPY OUT */ | ||||
| @@ -407,6 +424,19 @@ struct pg_conn | ||||
| 	pg_conn_host *connhost;		/* details about each named host */ | ||||
| 	char	   *connip;			/* IP address for current network connection */ | ||||
|  | ||||
| 	/* | ||||
| 	 * The pending command queue as a singly-linked list.  Head is the command | ||||
| 	 * currently in execution, tail is where new commands are added. | ||||
| 	 */ | ||||
| 	PGcmdQueueEntry *cmd_queue_head; | ||||
| 	PGcmdQueueEntry *cmd_queue_tail; | ||||
|  | ||||
| 	/* | ||||
| 	 * To save malloc traffic, we don't free entries right away; instead we | ||||
| 	 * save them in this list for possible reuse. | ||||
| 	 */ | ||||
| 	PGcmdQueueEntry *cmd_queue_recycle; | ||||
|  | ||||
| 	/* Connection data */ | ||||
| 	pgsocket	sock;			/* FD for socket, PGINVALID_SOCKET if | ||||
| 								 * unconnected */ | ||||
| @@ -622,6 +652,7 @@ extern void pqSaveMessageField(PGresult *res, char code, | ||||
| extern void pqSaveParameterStatus(PGconn *conn, const char *name, | ||||
| 								  const char *value); | ||||
| extern int	pqRowProcessor(PGconn *conn, const char **errmsgp); | ||||
| extern void pqCommandQueueAdvance(PGconn *conn); | ||||
| extern int	PQsendQueryContinue(PGconn *conn, const char *query); | ||||
|  | ||||
| /* === in fe-protocol3.c === */ | ||||
| @@ -795,6 +826,11 @@ extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); | ||||
|  */ | ||||
| #define pqIsnonblocking(conn)	((conn)->nonblocking) | ||||
|  | ||||
| /* | ||||
|  * Connection's outbuffer threshold, for pipeline mode. | ||||
|  */ | ||||
| #define OUTBUFFER_THRESHOLD	65536 | ||||
|  | ||||
| #ifdef ENABLE_NLS | ||||
| extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); | ||||
| extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user