mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Revise backend libpq interfaces so that messages to the frontend
can be generated in a buffer and then sent to the frontend in a single libpq call. This solves problems with NOTICE and ERROR messages generated in the middle of a data message or COPY OUT operation.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.44 1999/02/13 23:15:00 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.45 1999/04/25 03:19:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -94,6 +94,7 @@
|
||||
#include "fmgr.h"
|
||||
#include "lib/dllist.h"
|
||||
#include "libpq/libpq.h"
|
||||
#include "libpq/pqformat.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/lmgr.h"
|
||||
@@ -798,9 +799,12 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID)
|
||||
{
|
||||
if (whereToSendOutput == Remote)
|
||||
{
|
||||
pq_putnchar("A", 1);
|
||||
pq_putint(listenerPID, sizeof(int32));
|
||||
pq_putstr(relname);
|
||||
StringInfoData buf;
|
||||
pq_beginmessage(&buf);
|
||||
pq_sendbyte(&buf, 'A');
|
||||
pq_sendint(&buf, listenerPID, sizeof(int32));
|
||||
pq_sendstring(&buf, relname, strlen(relname));
|
||||
pq_endmessage(&buf);
|
||||
/* NOTE: we do not do pq_flush() here. For a self-notify, it will
|
||||
* happen at the end of the transaction, and for incoming notifies
|
||||
* ProcessIncomingNotify will do it after finding all the notifies.
|
||||
|
@@ -6,7 +6,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.73 1999/02/13 23:15:04 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.74 1999/04/25 03:19:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -89,12 +89,14 @@ inline void CopyDonePeek(FILE *fp, int c, int pickup);
|
||||
*
|
||||
* CopySendString does the same for null-terminated strings
|
||||
* CopySendChar does the same for single characters
|
||||
*
|
||||
* NB: no data conversion is applied by these functions
|
||||
*/
|
||||
inline void CopySendData(void *databuf, int datasize, FILE *fp) {
|
||||
if (!fp)
|
||||
pq_putnchar(databuf, datasize);
|
||||
pq_putbytes((char*) databuf, datasize);
|
||||
else
|
||||
fwrite(databuf, datasize, 1, fp);
|
||||
fwrite(databuf, datasize, 1, fp);
|
||||
}
|
||||
|
||||
inline void CopySendString(char *str, FILE *fp) {
|
||||
@@ -112,17 +114,24 @@ inline void CopySendChar(char c, FILE *fp) {
|
||||
*
|
||||
* CopyGetChar does the same for single characters
|
||||
* CopyGetEof checks if it's EOF on the input
|
||||
*
|
||||
* NB: no data conversion is applied by these functions
|
||||
*/
|
||||
inline void CopyGetData(void *databuf, int datasize, FILE *fp) {
|
||||
if (!fp)
|
||||
pq_getnchar(databuf, 0, datasize);
|
||||
pq_getbytes((char*) databuf, datasize);
|
||||
else
|
||||
fread(databuf, datasize, 1, fp);
|
||||
}
|
||||
|
||||
inline int CopyGetChar(FILE *fp) {
|
||||
if (!fp)
|
||||
return pq_getchar();
|
||||
{
|
||||
unsigned char ch;
|
||||
if (pq_getbytes((char*) &ch, 1))
|
||||
return EOF;
|
||||
return ch;
|
||||
}
|
||||
else
|
||||
return getc(fp);
|
||||
}
|
||||
@@ -143,7 +152,7 @@ inline int CopyGetEof(FILE *fp) {
|
||||
*/
|
||||
inline int CopyPeekChar(FILE *fp) {
|
||||
if (!fp)
|
||||
return pq_peekchar();
|
||||
return pq_peekbyte();
|
||||
else
|
||||
return getc(fp);
|
||||
}
|
||||
@@ -153,7 +162,7 @@ inline void CopyDonePeek(FILE *fp, int c, int pickup) {
|
||||
if (pickup) {
|
||||
/* We want to pick it up - just receive again into dummy buffer */
|
||||
char c;
|
||||
pq_getnchar(&c, 0, 1);
|
||||
pq_getbytes(&c, 1);
|
||||
}
|
||||
/* If we didn't want to pick it up, just leave it where it sits */
|
||||
}
|
||||
@@ -216,7 +225,10 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
* descriptor leak. bjm 1998/08/29
|
||||
*/
|
||||
if (file_opened)
|
||||
{
|
||||
FreeFile(fp);
|
||||
file_opened = false;
|
||||
}
|
||||
|
||||
rel = heap_openr(relname);
|
||||
if (rel == NULL)
|
||||
@@ -271,6 +283,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
if (IsUnderPostmaster)
|
||||
{
|
||||
SendCopyBegin();
|
||||
pq_startcopyout();
|
||||
fp = NULL;
|
||||
}
|
||||
else
|
||||
@@ -301,9 +314,12 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
FreeFile(fp);
|
||||
file_opened = false;
|
||||
}
|
||||
else if (!from && !binary)
|
||||
else if (!from)
|
||||
{
|
||||
CopySendData("\\.\n",3,fp);
|
||||
if (!binary)
|
||||
CopySendData("\\.\n",3,fp);
|
||||
if (IsUnderPostmaster)
|
||||
pq_endcopyout(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
* $Id: explain.c,v 1.34 1999/04/23 21:23:48 momjian Exp $
|
||||
* $Id: explain.c,v 1.35 1999/04/25 03:19:09 tgl Exp $
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -350,18 +350,13 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
||||
static char *
|
||||
Explain_PlanToString(Plan *plan, ExplainState *es)
|
||||
{
|
||||
StringInfo str;
|
||||
char *s;
|
||||
StringInfoData str;
|
||||
|
||||
if (plan == NULL)
|
||||
return "";
|
||||
Assert(plan != NULL);
|
||||
str = makeStringInfo();
|
||||
explain_outNode(str, plan, 0, es);
|
||||
s = str->data;
|
||||
pfree(str);
|
||||
|
||||
return s;
|
||||
/* see stringinfo.h for an explanation of this maneuver */
|
||||
initStringInfo(&str);
|
||||
if (plan != NULL)
|
||||
explain_outNode(&str, plan, 0, es);
|
||||
return str.data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user