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
* $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
}
}

@ -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

@ -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)
{
/*

@ -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;

@ -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);

Loading…
Cancel
Save