From: Magnus Hagander <mha@sollentuna.net>


			
			
				REL6_5_PATCHES
			
			
		
Marc G. Fournier 27 years ago
parent 6d5d673ca8
commit 3b3ffc8d97
  1. 205
      src/backend/commands/copy.c
  2. 27
      src/backend/libpq/pqcomm.c
  3. 11
      src/backend/utils/error/elog.c
  4. 4
      src/include/libpq/libpq-be.h
  5. 4
      src/include/libpq/libpq.h

@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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/copy.h>
#include "commands/trigger.h" #include "commands/trigger.h"
#include <storage/fd.h> #include <storage/fd.h>
#include <libpq/libpq.h>
#ifdef MULTIBYTE #ifdef MULTIBYTE
#include "mb/pg_wchar.h" #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 void CopyAttributeOut(FILE *fp, char *string, char *delim, int is_array);
static int CountTuples(Relation relation); static int CountTuples(Relation relation);
extern FILE *Pfout,
*Pfin;
static int lineno; 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. * DoCopy executes a the SQL COPY statement.
*/ */
@ -147,7 +243,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (IsUnderPostmaster) if (IsUnderPostmaster)
{ {
ReceiveCopyBegin(); ReceiveCopyBegin();
fp = Pfin; fp = NULL;
} }
else else
fp = stdin; fp = stdin;
@ -171,7 +267,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
if (IsUnderPostmaster) if (IsUnderPostmaster)
{ {
SendCopyBegin(); SendCopyBegin();
fp = Pfout; fp = NULL;
} }
else else
fp = stdout; fp = stdout;
@ -199,9 +295,9 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
} }
else if (!from && !binary) else if (!from && !binary)
{ {
fputs("\\.\n", fp); CopySendData("\\.\n",3,fp);
if (IsUnderPostmaster) if (IsUnderPostmaster)
fflush(Pfout); pq_flush();
} }
} }
} }
@ -269,7 +365,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
/* XXX expensive */ /* XXX expensive */
ntuples = CountTuples(rel); ntuples = CountTuples(rel);
fwrite(&ntuples, sizeof(int32), 1, fp); CopySendData(&ntuples, sizeof(int32), fp);
} }
while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0))) 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) if (oids && !binary)
{ {
fputs(oidout(tuple->t_data->t_oid), fp); CopySendString(oidout(tuple->t_data->t_oid),fp);
fputc(delim[0], fp); CopySendChar(delim[0],fp);
} }
for (i = 0; i < attr_count; i++) for (i = 0; i < attr_count; i++)
@ -294,10 +390,10 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
pfree(string); pfree(string);
} }
else else
fputs("\\N", fp); /* null indicator */ CopySendString("\\N", fp); /* null indicator */
if (i == attr_count - 1) if (i == attr_count - 1)
fputc('\n', fp); CopySendChar('\n', fp);
else 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 * when copying out, only use the first char of the
* delim string * delim string
*/ */
fputc(delim[0], fp); CopySendChar(delim[0], fp);
} }
} }
else 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; length = tuple->t_len - tuple->t_data->t_hoff;
fwrite(&length, sizeof(int32), 1, fp); CopySendData(&length, sizeof(int32), fp);
if (oids) 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) if (null_ct > 0)
{ {
for (i = 0; i < attr_count; i++) for (i = 0; i < attr_count; i++)
{ {
if (nulls[i] == 'n') if (nulls[i] == 'n')
{ {
fwrite(&i, sizeof(int32), 1, fp); CopySendData(&i, sizeof(int32), fp);
nulls[i] = ' '; nulls[i] = ' ';
} }
} }
} }
fwrite((char *) tuple->t_data + tuple->t_data->t_hoff, CopySendData((char *) tuple->t_data + tuple->t_data->t_hoff,
length, 1, fp); length, fp);
} }
} }
@ -527,7 +623,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
in_functions = NULL; in_functions = NULL;
elements = NULL; elements = NULL;
typmod = NULL; typmod = NULL;
fread(&ntuples, sizeof(int32), 1, fp); CopyGetData(&ntuples, sizeof(int32), fp);
if (ntuples != 0) if (ntuples != 0)
reading_to_eof = false; reading_to_eof = false;
} }
@ -544,10 +640,12 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
index_nulls[i] = ' '; index_nulls[i] = ' ';
byval[i] = (bool) IsTypeByVal(attr[i]->atttypid); byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
} }
values = (Datum *) palloc(sizeof(Datum) * attr_count);
lineno = 0; lineno = 0;
while (!done) while (!done)
{ {
values = (Datum *) palloc(sizeof(Datum) * attr_count);
if (!binary) if (!binary)
{ {
#ifdef COPY_PATCH #ifdef COPY_PATCH
@ -608,29 +706,29 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
} }
else else
{ /* binary */ { /* binary */
fread(&len, sizeof(int32), 1, fp); CopyGetData(&len, sizeof(int32), fp);
if (feof(fp)) if (CopyGetEof(fp))
done = 1; done = 1;
else else
{ {
if (oids) if (oids)
{ {
fread(&loaded_oid, sizeof(int32), 1, fp); CopyGetData(&loaded_oid, sizeof(int32), fp);
if (loaded_oid < BootstrapObjectIdData) if (loaded_oid < BootstrapObjectIdData)
elog(ERROR, "COPY BINARY: Invalid Oid line: %d", lineno); 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) if (null_ct > 0)
{ {
for (i = 0; i < null_ct; i++) for (i = 0; i < null_ct; i++)
{ {
fread(&null_id, sizeof(int32), 1, fp); CopyGetData(&null_id, sizeof(int32), fp);
nulls[null_id] = 'n'; nulls[null_id] = 'n';
} }
} }
string = (char *) palloc(len); string = (char *) palloc(len);
fread(string, len, 1, fp); CopyGetData(string, len, fp);
ptr = string; ptr = string;
@ -979,7 +1077,7 @@ CopyReadNewline(FILE *fp, int *newline)
if (!*newline) if (!*newline)
{ {
elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored", lineno); elog(NOTICE, "CopyReadNewline: line %d - extra fields ignored", lineno);
while (!feof(fp) && (getc(fp) != '\n')); while (!CopyGetEof(fp) && (CopyGetChar(fp) != '\n'));
} }
*newline = 0; *newline = 0;
} }
@ -1028,19 +1126,19 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
#endif #endif
*isnull = (bool) false; /* set default */ *isnull = (bool) false; /* set default */
if (feof(fp)) if (CopyGetEof(fp))
return NULL; return NULL;
while (!done) while (!done)
{ {
c = getc(fp); c = CopyGetChar(fp);
if (feof(fp)) if (CopyGetEof(fp))
return NULL; return NULL;
else if (c == '\\') else if (c == '\\')
{ {
c = getc(fp); c = CopyGetChar(fp);
if (feof(fp)) if (CopyGetEof(fp))
return NULL; return NULL;
switch (c) switch (c)
{ {
@ -1056,25 +1154,30 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
int val; int val;
val = VALUE(c); val = VALUE(c);
c = getc(fp); c = CopyPeekChar(fp);
if (ISOCTAL(c)) if (ISOCTAL(c))
{ {
val = (val << 3) + VALUE(c); val = (val << 3) + VALUE(c);
c = getc(fp); CopyDonePeek(fp, c, 1); /* Pick up the character! */
if (ISOCTAL(c)) c = CopyPeekChar(fp);
if (ISOCTAL(c)) {
CopyDonePeek(fp,c,1); /* pick up! */
val = (val << 3) + VALUE(c); val = (val << 3) + VALUE(c);
}
else else
{ {
if (feof(fp)) if (CopyGetEof(fp)) {
CopyDonePeek(fp,c,1); /* pick up */
return NULL; return NULL;
ungetc(c, fp); }
CopyDonePeek(fp,c,0); /* Return to stream! */
} }
} }
else else
{ {
if (feof(fp)) if (CopyGetEof(fp))
return NULL; return NULL;
ungetc(c, fp); CopyDonePeek(fp,c,0); /* Return to stream! */
} }
c = val & 0377; c = val & 0377;
} }
@ -1102,7 +1205,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
*isnull = (bool) true; *isnull = (bool) true;
break; break;
case '.': case '.':
c = getc(fp); c = CopyGetChar(fp);
if (c != '\n') if (c != '\n')
elog(ERROR, "CopyReadAttribute - end of record marker corrupted. line: %d", lineno); elog(ERROR, "CopyReadAttribute - end of record marker corrupted. line: %d", lineno);
return NULL; return NULL;
@ -1125,8 +1228,8 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim)
mblen--; mblen--;
for (j = 0; j < mblen; j++) for (j = 0; j < mblen; j++)
{ {
c = getc(fp); c = CopyGetChar(fp);
if (feof(fp)) if (CopyGetEof(fp))
return NULL; return NULL;
attribute[i++] = c; attribute[i++] = c;
} }
@ -1171,29 +1274,29 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim, int is_array)
{ {
if (c == delim[0] || c == '\n' || if (c == delim[0] || c == '\n' ||
(c == '\\' && !is_array)) (c == '\\' && !is_array))
fputc('\\', fp); CopySendChar('\\', fp);
else if (c == '\\' && is_array) else if (c == '\\' && is_array)
{ {
if (*(string + 1) == '\\') if (*(string + 1) == '\\')
{ {
/* translate \\ to \\\\ */ /* translate \\ to \\\\ */
fputc('\\', fp); CopySendChar('\\', fp);
fputc('\\', fp); CopySendChar('\\', fp);
fputc('\\', fp); CopySendChar('\\', fp);
string++; string++;
} }
else if (*(string + 1) == '"') else if (*(string + 1) == '"')
{ {
/* translate \" to \\\" */ /* translate \" to \\\" */
fputc('\\', fp); CopySendChar('\\', fp);
fputc('\\', fp); CopySendChar('\\', fp);
} }
} }
#ifdef MULTIBYTE #ifdef MULTIBYTE
for (i = 0; i < mblen; i++) for (i = 0; i < mblen; i++)
fputc(*(string + i), fp); CopySendChar(*(string + i), fp);
#else #else
fputc(*string, fp); CopySendChar(*string, fp);
#endif #endif
} }
} }

@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * declarations
* ---------------- * ----------------
*/ */
FILE *Pfout, static FILE *Pfout,
*Pfin, *Pfin,
*Pfdebug; /* debugging libpq */ *Pfdebug; /* debugging libpq */
@ -98,7 +98,7 @@ pq_init(int fd)
} }
/* ------------------------- /* -------------------------
* pq_getc(File* fin) * pq_getchar()
* *
* get a character from the input file, * get a character from the input file,
* *
@ -107,20 +107,29 @@ pq_init(int fd)
* used for debugging libpq * used for debugging libpq
*/ */
#if 0 /* not used anymore */ int
pq_getchar(void)
static int
pq_getc(FILE *fin)
{ {
int c; int c;
c = getc(fin); c = getc(Pfin);
if (Pfdebug && c != EOF) if (Pfdebug && c != EOF)
putc(c, Pfdebug); putc(c, Pfdebug);
return c; 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 * pq_gettty - return the name of the tty in the given buffer

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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, extern int errno,
sys_nerr; sys_nerr;
#ifndef PG_STANDALONE
extern FILE *Pfout;
#endif
#ifdef USE_SYSLOG #ifdef USE_SYSLOG
int log_level; int log_level;
@ -190,7 +185,7 @@ elog(int lev, const char *fmt,...)
#ifndef PG_STANDALONE #ifndef PG_STANDALONE
/* Send IPC message to the front-end program */ /* 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 */ /* notices are not exactly errors, handle it differently */
if (lev == NOTICE) if (lev == NOTICE)
@ -201,7 +196,7 @@ elog(int lev, const char *fmt,...)
pq_putstr(line + TIMESTAMP_SIZE); /* don't show timestamps */ pq_putstr(line + TIMESTAMP_SIZE); /* don't show timestamps */
pq_flush(); pq_flush();
} }
if (Pfout == NULL) if (!IsUnderPostmaster)
{ {
/* /*

@ -7,7 +7,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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; } Port;
extern FILE *Pfout,
*Pfin;
extern ProtocolVersion FrontendProtocol; extern ProtocolVersion FrontendProtocol;

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 pq_getstr(char *s, int maxlen);
extern int PQgetline(char *s, int maxlen); extern int PQgetline(char *s, int maxlen);
extern int PQputline(char *s); 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_getnchar(char *s, int off, int maxlen);
extern int pq_getint(int b); extern int pq_getint(int b);
extern void pq_putstr(char *s); extern void pq_putstr(char *s);

Loading…
Cancel
Save