Commit 40cad8b6 authored by Tom Lane's avatar Tom Lane

My first cut at libpq revision didn't handle MULTIBYTE correctly,

but I think it's OK now...
parent fad6f292
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.43 1999/04/25 03:19:23 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.44 1999/04/25 19:27:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,10 +25,6 @@ ...@@ -25,10 +25,6 @@
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
static void printtup_setup(DestReceiver* self, TupleDesc typeinfo); static void printtup_setup(DestReceiver* self, TupleDesc typeinfo);
static void printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self); static void printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self);
static void printtup_cleanup(DestReceiver* self); static void printtup_cleanup(DestReceiver* self);
...@@ -157,14 +153,10 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self) ...@@ -157,14 +153,10 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self)
StringInfoData buf; StringInfoData buf;
int i, int i,
j, j,
k, k;
outputlen;
char *outputstr; char *outputstr;
Datum attr; Datum attr;
bool isnull; bool isnull;
#ifdef MULTIBYTE
unsigned char *p;
#endif
/* Set or update my derived attribute info, if needed */ /* Set or update my derived attribute info, if needed */
if (myState->attrinfo != typeinfo || if (myState->attrinfo != typeinfo ||
...@@ -213,24 +205,13 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self) ...@@ -213,24 +205,13 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self)
{ {
outputstr = (char *) (*fmgr_faddr(&thisState->finfo)) outputstr = (char *) (*fmgr_faddr(&thisState->finfo))
(attr, thisState->typelem, typeinfo->attrs[i]->atttypmod); (attr, thisState->typelem, typeinfo->attrs[i]->atttypmod);
#ifdef MULTIBYTE pq_sendcountedtext(&buf, outputstr, strlen(outputstr));
p = pg_server_to_client(outputstr, strlen(outputstr));
outputlen = strlen(p);
pq_sendint(&buf, outputlen + VARHDRSZ, VARHDRSZ);
pq_sendbytes(&buf, p, outputlen);
#else
outputlen = strlen(outputstr);
pq_sendint(&buf, outputlen + VARHDRSZ, VARHDRSZ);
pq_sendbytes(&buf, outputstr, outputlen);
#endif
pfree(outputstr); pfree(outputstr);
} }
else else
{ {
outputstr = "<unprintable>"; outputstr = "<unprintable>";
outputlen = strlen(outputstr); pq_sendcountedtext(&buf, outputstr, strlen(outputstr));
pq_sendint(&buf, outputlen + VARHDRSZ, VARHDRSZ);
pq_sendbytes(&buf, outputstr, outputlen);
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.45 1999/04/25 03:19:08 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.46 1999/04/25 19:27:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -803,7 +803,7 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID) ...@@ -803,7 +803,7 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID)
pq_beginmessage(&buf); pq_beginmessage(&buf);
pq_sendbyte(&buf, 'A'); pq_sendbyte(&buf, 'A');
pq_sendint(&buf, listenerPID, sizeof(int32)); pq_sendint(&buf, listenerPID, sizeof(int32));
pq_sendstring(&buf, relname, strlen(relname)); pq_sendstring(&buf, relname);
pq_endmessage(&buf); pq_endmessage(&buf);
/* NOTE: we do not do pq_flush() here. For a self-notify, it will /* 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 * happen at the end of the transaction, and for incoming notifies
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqformat.c,v 1.1 1999/04/25 03:19:22 tgl Exp $ * $Id: pqformat.c,v 1.2 1999/04/25 19:27:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* pq_sendbyte - append a raw byte to a StringInfo buffer * pq_sendbyte - append a raw byte to a StringInfo buffer
* pq_sendint - append a binary integer to a StringInfo buffer * pq_sendint - append a binary integer to a StringInfo buffer
* pq_sendbytes - append raw data to a StringInfo buffer * pq_sendbytes - append raw data to a StringInfo buffer
* pq_sendtext - append a text string (with MULTIBYTE conversion) * pq_sendcountedtext - append a text string (with MULTIBYTE conversion)
* pq_sendstring - append a null-terminated text string (with MULTIBYTE) * pq_sendstring - append a null-terminated text string (with MULTIBYTE)
* pq_endmessage - send the completed message to the frontend * pq_endmessage - send the completed message to the frontend
* Note: it is also possible to append data to the StringInfo buffer using * Note: it is also possible to append data to the StringInfo buffer using
...@@ -36,9 +36,8 @@ ...@@ -36,9 +36,8 @@
* Message input: * Message input:
* pq_getint - get an integer from connection * pq_getint - get an integer from connection
* pq_getstr - get a null terminated string from connection * pq_getstr - get a null terminated string from connection
* pq_getnchar - get n characters from connection, and null-terminate * pq_getstr performs MULTIBYTE conversion on the collected string.
* pq_getstr and pq_getnchar perform MULTIBYTE conversion on the collected * Use the raw pqcomm.c routines pq_getstring or pq_getbytes
* string. Use the raw pqcomm.c routines pq_getstring and pq_getbytes
* to fetch data without conversion. * to fetch data without conversion.
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -48,6 +47,7 @@ ...@@ -48,6 +47,7 @@
#ifdef MULTIBYTE #ifdef MULTIBYTE
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#endif #endif
#include <string.h>
#ifdef HAVE_ENDIAN_H #ifdef HAVE_ENDIAN_H
#include <endian.h> #include <endian.h>
#endif #endif
...@@ -110,36 +110,49 @@ pq_sendbytes(StringInfo buf, const char *data, int datalen) ...@@ -110,36 +110,49 @@ pq_sendbytes(StringInfo buf, const char *data, int datalen)
} }
/* -------------------------------- /* --------------------------------
* pq_sendtext - append a text string (with MULTIBYTE conversion) * pq_sendcountedtext - append a text string (with MULTIBYTE conversion)
* *
* NB: passed text string must be null-terminated, even though we expect * The data sent to the frontend by this routine is a 4-byte count field
* the caller to hand us the length (this is just because the caller * (the count includes itself, by convention) followed by the string.
* usually knows the length anyway). In this routine, the data sent to * The passed text string need not be null-terminated, and the data sent
* the frontend is NOT null-terminated. * to the frontend isn't either.
* -------------------------------- * --------------------------------
*/ */
void void
pq_sendtext(StringInfo buf, const char *str, int slen) pq_sendcountedtext(StringInfo buf, const char *str, int slen)
{ {
#ifdef MULTIBYTE #ifdef MULTIBYTE
str = (const char *) pg_server_to_client(str, slen); const char *p;
p = (const char *) pg_server_to_client((unsigned char *) str, slen);
if (p != str) /* actual conversion has been done? */
{
str = p;
slen = strlen(str);
}
#endif #endif
pq_sendint(buf, slen + 4, 4);
appendBinaryStringInfo(buf, str, slen); appendBinaryStringInfo(buf, str, slen);
} }
/* -------------------------------- /* --------------------------------
* pq_sendstring - append a null-terminated text string (with MULTIBYTE) * pq_sendstring - append a null-terminated text string (with MULTIBYTE)
* *
* NB: passed text string must be null-terminated, even though we expect * NB: passed text string must be null-terminated, and so is the data
* the caller to hand us the length (this is just because the caller * sent to the frontend.
* usually knows the length anyway).
* -------------------------------- * --------------------------------
*/ */
void void
pq_sendstring(StringInfo buf, const char *str, int slen) pq_sendstring(StringInfo buf, const char *str)
{ {
int slen = strlen(str);
#ifdef MULTIBYTE #ifdef MULTIBYTE
str = (const char *) pg_server_to_client(str, slen); const char *p;
p = (const char *) pg_server_to_client((unsigned char *) str, slen);
if (p != str) /* actual conversion has been done? */
{
str = p;
slen = strlen(str);
}
#endif #endif
appendBinaryStringInfo(buf, str, slen+1); appendBinaryStringInfo(buf, str, slen+1);
} }
...@@ -258,35 +271,18 @@ pq_getstr(char *s, int maxlen) ...@@ -258,35 +271,18 @@ pq_getstr(char *s, int maxlen)
c = pq_getstring(s, maxlen); c = pq_getstring(s, maxlen);
#ifdef MULTIBYTE #ifdef MULTIBYTE
p = (char*) pg_client_to_server((unsigned char *) s, maxlen); p = (char*) pg_client_to_server((unsigned char *) s, strlen(s));
if (s != p) /* actual conversion has been done? */ if (p != s) /* actual conversion has been done? */
strcpy(s, p); {
#endif int newlen = strlen(p);
if (newlen < maxlen)
return c; strcpy(s, p);
} else
{
/* -------------------------------- strncpy(s, p, maxlen);
* pq_getnchar - get n characters from connection, and null-terminate s[maxlen-1] = '\0';
* }
* returns 0 if OK, EOF if trouble }
* --------------------------------
*/
int
pq_getnchar(char *s, int len)
{
int c;
#ifdef MULTIBYTE
char *p;
#endif
c = pq_getbytes(s, len);
s[len] = '\0';
#ifdef MULTIBYTE
p = (char*) pg_client_to_server((unsigned char *) s, len+1);
if (s != p) /* actual conversion has been done? */
strcpy(s, p);
#endif #endif
return c; return c;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.26 1999/04/25 03:19:09 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.27 1999/04/25 19:27:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -155,8 +155,7 @@ BeginCommand(char *pname, ...@@ -155,8 +155,7 @@ BeginCommand(char *pname,
for (i = 0; i < natts; ++i) for (i = 0; i < natts; ++i)
{ {
pq_sendstring(&buf, attrs[i]->attname.data, pq_sendstring(&buf, attrs[i]->attname.data);
strlen(attrs[i]->attname.data));
pq_sendint(&buf, (int) attrs[i]->atttypid, pq_sendint(&buf, (int) attrs[i]->atttypid,
sizeof(attrs[i]->atttypid)); sizeof(attrs[i]->atttypid));
pq_sendint(&buf, attrs[i]->attlen, pq_sendint(&buf, attrs[i]->attlen,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqformat.h,v 1.1 1999/04/25 03:19:14 tgl Exp $ * $Id: pqformat.h,v 1.2 1999/04/25 19:27:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,13 +19,12 @@ ...@@ -19,13 +19,12 @@
extern void pq_sendbyte(StringInfo buf, int byt); extern void pq_sendbyte(StringInfo buf, int byt);
extern void pq_sendbytes(StringInfo buf, const char *data, int datalen); extern void pq_sendbytes(StringInfo buf, const char *data, int datalen);
extern void pq_sendtext(StringInfo buf, const char *str, int slen); extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen);
extern void pq_sendstring(StringInfo buf, const char *str, int slen); extern void pq_sendstring(StringInfo buf, const char *str);
extern void pq_sendint(StringInfo buf, int i, int b); extern void pq_sendint(StringInfo buf, int i, int b);
extern void pq_endmessage(StringInfo buf); extern void pq_endmessage(StringInfo buf);
extern int pq_getint(int *result, int b); extern int pq_getint(int *result, int b);
extern int pq_getstr(char *s, int maxlen); extern int pq_getstr(char *s, int maxlen);
extern int pq_getnchar(char *s, int len);
#endif /* PQFORMAT_H */ #endif /* PQFORMAT_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment