From: Magnus Hagander <mha@sollentuna.net>

Here is a first patch to cleanup the backend side of libpq.
This patch removes all external dependencies on the "Pfin" and "Pfout" that
are declared in pqcomm.h. These variables are also changed to "static" to
make sure.
Almost all the change is in the handler of the "copy" command - most other
areas of the backend already used the correct functions.
This change will make the way for cleanup of the internal stuff there - now
that all the functions accessing the file descriptors are confined to a
single directory.
This commit is contained in:
Marc G. Fournier 1999-01-11 03:56:11 +00:00
parent 6d5d673ca8
commit 3b3ffc8d97
5 changed files with 179 additions and 72 deletions

View File

@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.65 1998/12/15 12:45:53 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.66 1999/01/11 03:56:05 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -36,6 +36,7 @@
#include <commands/copy.h>
#include "commands/trigger.h"
#include <storage/fd.h>
#include <libpq/libpq.h>
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
@ -67,11 +68,106 @@ static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim);
static void CopyAttributeOut(FILE *fp, char *string, char *delim, int is_array);
static int CountTuples(Relation relation);
extern FILE *Pfout,
*Pfin;
static int lineno;
/*
* Internal communications functions
*/
inline void CopySendData(void *databuf, int datasize, FILE *fp);
inline void CopySendString(char *str, FILE *fp);
inline void CopySendChar(char c, FILE *fp);
inline void CopyGetData(void *databuf, int datasize, FILE *fp);
inline int CopyGetChar(FILE *fp);
inline int CopyGetEof(FILE *fp);
inline int CopyPeekChar(FILE *fp);
inline void CopyDonePeek(FILE *fp, int c, int pickup);
/*
* CopySendData sends output data either to the file
* specified by fp or, if fp is NULL, using the standard
* backend->frontend functions
*
* CopySendString does the same for null-terminated strings
* CopySendChar does the same for single characters
*/
inline void CopySendData(void *databuf, int datasize, FILE *fp) {
if (!fp)
pq_putnchar(databuf, datasize);
else
fwrite(databuf, datasize, 1, fp);
}
inline void CopySendString(char *str, FILE *fp) {
CopySendData(str,strlen(str),fp);
}
inline void CopySendChar(char c, FILE *fp) {
CopySendData(&c,1,fp);
}
/*
* CopyGetData reads output data either from the file
* specified by fp or, if fp is NULL, using the standard
* backend->frontend functions
*
* CopyGetChar does the same for single characters
* CopyGetEof checks if it's EOF on the input
*/
inline void CopyGetData(void *databuf, int datasize, FILE *fp) {
if (!fp)
pq_getnchar(databuf, 0, datasize);
else
fread(databuf, datasize, 1, fp);
}
inline int CopyGetChar(FILE *fp) {
if (!fp)
return pq_getchar();
else
return getc(fp);
}
inline int CopyGetEof(FILE *fp) {
if (!fp)
return 0; /* Never return EOF when talking to frontend ? */
else
return feof(fp);
}
/*
* CopyPeekChar reads a byte in "peekable" mode.
* after each call to CopyPeekChar, a call to CopyDonePeek _must_
* follow.
* CopyDonePeek will either take the peeked char off the steam
* (if pickup is != 0) or leave it on the stream (if pickup == 0)
*/
inline int CopyPeekChar(FILE *fp) {
if (!fp)
return pq_peekchar();
else
return getc(fp);
}
inline void CopyDonePeek(FILE *fp, int c, int pickup) {
if (!fp) {
if (pickup) {
/* We want to pick it up - just receive again into dummy buffer */
char c;
pq_getnchar(&c, 0, 1);
}
/* If we didn't want to pick it up, just leave it where it sits */
}
else {
if (!pickup) {
/* We don't want to pick it up - so put it back in there */
ungetc(c,fp);
}
/* If we wanted to pick it up, it's already there */
}
}
/*
* DoCopy executes a the SQL COPY statement.
*/
@ -147,7 +243,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (IsUnderPostmaster)
{
ReceiveCopyBegin();
fp = Pfin;
fp = NULL;
}
else
fp = stdin;
@ -171,7 +267,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (IsUnderPostmaster)
{
SendCopyBegin();
fp = Pfout;
fp = NULL;
}
else
fp = stdout;
@ -199,9 +295,9 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
}
else if (!from && !binary)
{
fputs("\\.\n", fp);
CopySendData("\\.\n",3,fp);
if (IsUnderPostmaster)
fflush(Pfout);
pq_flush();
}
}
}
@ -269,7 +365,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
/* XXX expensive */
ntuples = CountTuples(rel);
fwrite(&ntuples, sizeof(int32), 1, fp);
CopySendData(&ntuples, sizeof(int32), fp);
}
while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
@ -277,8 +373,8 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
if (oids && !binary)
{
fputs(oidout(tuple->t_data->t_oid), fp);
fputc(delim[0], fp);
CopySendString(oidout(tuple->t_data->t_oid),fp);
CopySendChar(delim[0],fp);
}
for (i = 0; i < attr_count; i++)
@ -294,10 +390,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
pfree(string);
}
else
fputs("\\N", fp); /* null indicator */
CopySendString("\\N", fp); /* null indicator */
if (i == attr_count - 1)
fputc('\n', fp);
CopySendChar('\n', fp);
else
{
@ -305,7 +401,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
* when copying out, only use the first char of the
* delim string
*/
fputc(delim[0], fp);
CopySendChar(delim[0], fp);
}
}
else
@ -332,24 +428,24 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
}
length = tuple->t_len - tuple->t_data->t_hoff;
fwrite(&length, sizeof(int32), 1, fp);
CopySendData(&length, sizeof(int32), fp);
if (oids)
fwrite((char *) &tuple->t_data->t_oid, sizeof(int32), 1, fp);
CopySendData((char *) &tuple->t_data->t_oid, sizeof(int32), fp);
fwrite(&null_ct, sizeof(int32), 1, fp);
CopySendData(&null_ct, sizeof(int32), fp);
if (null_ct > 0)
{
for (i = 0; i < attr_count; i++)
{
if (nulls[i] == 'n')
{
fwrite(&i, sizeof(int32), 1, fp);
CopySendData(&i, sizeof(int32), fp);
nulls[i] = ' ';
}
}
}
fwrite((char *) tuple->t_data + tuple->t_data->t_hoff,
length, 1, fp);
CopySendData((char *) tuple->t_data + tuple->t_data->t_hoff,
length, fp);
}
}
@ -527,7 +623,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
in_functions = NULL;
elements = NULL;
typmod = NULL;
fread(&ntuples, sizeof(int32), 1, fp);
CopyGetData(&ntuples, sizeof(int32), fp);
if (ntuples != 0)
reading_to_eof = false;
}
@ -544,10 +640,12 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
index_nulls[i] = ' ';
byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
}
values = (Datum *) palloc(sizeof(Datum) * attr_count);
lineno = 0;
while (!done)
{
values = (Datum *) palloc(sizeof(Datum) * attr_count);
if (!binary)
{
#ifdef COPY_PATCH
@ -608,29 +706,29 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
}
else
{ /* binary */
fread(&len, sizeof(int32), 1, fp);
if (feof(fp))
CopyGetData(&len, sizeof(int32), fp);
if (CopyGetEof(fp))
done = 1;
else
{
if (oids)
{
fread(&loaded_oid, sizeof(int32), 1, fp);
CopyGetData(&loaded_oid, sizeof(int32), fp);
if (loaded_oid < BootstrapObjectIdData)
elog(ERROR, "COPY BINARY: Invalid Oid line: %d", lineno);
}
fread(&null_ct, sizeof(int32), 1, fp);
CopyGetData(&null_ct, sizeof(int32), fp);
if (null_ct > 0)
{
for (i = 0; i < null_ct; i++)
{
fread(&null_id, sizeof(int32), 1, fp);
CopyGetData(&null_id, sizeof(int32), fp);
nulls[null_id] = 'n';
}
}
string = (char *) palloc(len);
fread(string, len, 1, fp);
CopyGetData(string, len, fp);
ptr = string;
@ -979,7 +1077,7 @@ CopyReadNewline(FILE *fp, int *newline)
if (!*newline)
{
elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored", lineno);
while (!feof(fp) && (getc(fp) != '\n'));
while (!CopyGetEof(fp) && (CopyGetChar(fp) != '\n'));
}
*newline = 0;
}
@ -1028,19 +1126,19 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
#endif
*isnull = (bool) false; /* set default */
if (feof(fp))
if (CopyGetEof(fp))
return NULL;
while (!done)
{
c = getc(fp);
c = CopyGetChar(fp);
if (feof(fp))
if (CopyGetEof(fp))
return NULL;
else if (c == '\\')
{
c = getc(fp);
if (feof(fp))
c = CopyGetChar(fp);
if (CopyGetEof(fp))
return NULL;
switch (c)
{
@ -1056,25 +1154,30 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
int val;
val = VALUE(c);
c = getc(fp);
c = CopyPeekChar(fp);
if (ISOCTAL(c))
{
val = (val << 3) + VALUE(c);
c = getc(fp);
if (ISOCTAL(c))
CopyDonePeek(fp, c, 1); /* Pick up the character! */
c = CopyPeekChar(fp);
if (ISOCTAL(c)) {
CopyDonePeek(fp,c,1); /* pick up! */
val = (val << 3) + VALUE(c);
}
else
{
if (feof(fp))
if (CopyGetEof(fp)) {
CopyDonePeek(fp,c,1); /* pick up */
return NULL;
ungetc(c, fp);
}
CopyDonePeek(fp,c,0); /* Return to stream! */
}
}
else
{
if (feof(fp))
if (CopyGetEof(fp))
return NULL;
ungetc(c, fp);
CopyDonePeek(fp,c,0); /* Return to stream! */
}
c = val & 0377;
}
@ -1102,7 +1205,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
*isnull = (bool) true;
break;
case '.':
c = getc(fp);
c = CopyGetChar(fp);
if (c != '\n')
elog(ERROR, "CopyReadAttribute - end of record marker corrupted. line: %d", lineno);
return NULL;
@ -1125,8 +1228,8 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
mblen--;
for (j = 0; j < mblen; j++)
{
c = getc(fp);
if (feof(fp))
c = CopyGetChar(fp);
if (CopyGetEof(fp))
return NULL;
attribute[i++] = c;
}
@ -1171,29 +1274,29 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim, int is_array)
{
if (c == delim[0] || c == '\n' ||
(c == '\\' && !is_array))
fputc('\\', fp);
CopySendChar('\\', fp);
else if (c == '\\' && is_array)
{
if (*(string + 1) == '\\')
{
/* translate \\ to \\\\ */
fputc('\\', fp);
fputc('\\', fp);
fputc('\\', fp);
CopySendChar('\\', fp);
CopySendChar('\\', fp);
CopySendChar('\\', fp);
string++;
}
else if (*(string + 1) == '"')
{
/* translate \" to \\\" */
fputc('\\', fp);
fputc('\\', fp);
CopySendChar('\\', fp);
CopySendChar('\\', fp);
}
}
#ifdef MULTIBYTE
for (i = 0; i < mblen; i++)
fputc(*(string + i), fp);
CopySendChar(*(string + i), fp);
#else
fputc(*string, fp);
CopySendChar(*string, fp);
#endif
}
}

View File

@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: pqcomm.c,v 1.59 1998/12/14 06:50:27 scrappy Exp $
* $Id: pqcomm.c,v 1.60 1999/01/11 03:56:06 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -75,7 +75,7 @@
* declarations
* ----------------
*/
FILE *Pfout,
static FILE *Pfout,
*Pfin,
*Pfdebug; /* debugging libpq */
@ -98,7 +98,7 @@ pq_init(int fd)
}
/* -------------------------
* pq_getc(File* fin)
* pq_getchar()
*
* get a character from the input file,
*
@ -107,20 +107,29 @@ pq_init(int fd)
* used for debugging libpq
*/
#if 0 /* not used anymore */
static int
pq_getc(FILE *fin)
int
pq_getchar(void)
{
int c;
c = getc(fin);
c = getc(Pfin);
if (Pfdebug && c != EOF)
putc(c, Pfdebug);
return c;
}
#endif
/*
* --------------------------------
* pq_peekchar - get 1 character from connection, but leave it in the stream
*/
int
pq_peekchar(void) {
char c = getc(Pfin);
ungetc(c,Pfin);
return c;
}
/* --------------------------------
* pq_gettty - return the name of the tty in the given buffer

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.36 1999/01/01 04:48:45 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.37 1999/01/11 03:56:07 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -67,11 +67,6 @@ elog(int lev, const char *fmt,...)
extern int errno,
sys_nerr;
#ifndef PG_STANDALONE
extern FILE *Pfout;
#endif
#ifdef USE_SYSLOG
int log_level;
@ -190,7 +185,7 @@ elog(int lev, const char *fmt,...)
#ifndef PG_STANDALONE
/* Send IPC message to the front-end program */
if (Pfout != NULL && lev > DEBUG)
if (IsUnderPostmaster && lev > DEBUG)
{
/* notices are not exactly errors, handle it differently */
if (lev == NOTICE)
@ -201,7 +196,7 @@ elog(int lev, const char *fmt,...)
pq_putstr(line + TIMESTAMP_SIZE); /* don't show timestamps */
pq_flush();
}
if (Pfout == NULL)
if (!IsUnderPostmaster)
{
/*

View File

@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-be.h,v 1.12 1998/09/01 04:36:27 momjian Exp $
* $Id: libpq-be.h,v 1.13 1999/01/11 03:56:11 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -131,8 +131,6 @@ typedef struct Port
} Port;
extern FILE *Pfout,
*Pfin;
extern ProtocolVersion FrontendProtocol;

View File

@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq.h,v 1.21 1998/09/01 04:36:29 momjian Exp $
* $Id: libpq.h,v 1.22 1999/01/11 03:56:11 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@ -258,6 +258,8 @@ extern void pq_flush(void);
extern int pq_getstr(char *s, int maxlen);
extern int PQgetline(char *s, int maxlen);
extern int PQputline(char *s);
extern int pq_getchar(void);
extern int pq_peekchar(void);
extern int pq_getnchar(char *s, int off, int maxlen);
extern int pq_getint(int b);
extern void pq_putstr(char *s);