From 40cad8b66f468d627781704781f6f1877548e73a Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Sun, 25 Apr 1999 19:27:47 +0000 Subject: [PATCH] My first cut at libpq revision didn't handle MULTIBYTE correctly, but I think it's OK now... --- src/backend/access/common/printtup.c | 27 ++------- src/backend/commands/async.c | 4 +- src/backend/libpq/pqformat.c | 88 +++++++++++++--------------- src/backend/tcop/dest.c | 5 +- src/include/libpq/pqformat.h | 7 +-- 5 files changed, 53 insertions(+), 78 deletions(-) diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c index 5ce4830ebd4..0d2aeeecd1c 100644 --- a/src/backend/access/common/printtup.c +++ b/src/backend/access/common/printtup.c @@ -8,7 +8,7 @@ * * * 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 @@ #include "libpq/pqformat.h" #include "utils/syscache.h" -#ifdef MULTIBYTE -#include "mb/pg_wchar.h" -#endif - static void printtup_setup(DestReceiver* self, TupleDesc typeinfo); static void printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self); static void printtup_cleanup(DestReceiver* self); @@ -157,14 +153,10 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self) StringInfoData buf; int i, j, - k, - outputlen; + k; char *outputstr; Datum attr; bool isnull; -#ifdef MULTIBYTE - unsigned char *p; -#endif /* Set or update my derived attribute info, if needed */ if (myState->attrinfo != typeinfo || @@ -213,24 +205,13 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver* self) { outputstr = (char *) (*fmgr_faddr(&thisState->finfo)) (attr, thisState->typelem, typeinfo->attrs[i]->atttypmod); -#ifdef MULTIBYTE - 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 + pq_sendcountedtext(&buf, outputstr, strlen(outputstr)); pfree(outputstr); } else { outputstr = "<unprintable>"; - outputlen = strlen(outputstr); - pq_sendint(&buf, outputlen + VARHDRSZ, VARHDRSZ); - pq_sendbytes(&buf, outputstr, outputlen); + pq_sendcountedtext(&buf, outputstr, strlen(outputstr)); } } diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 3d5cf92f7d1..fb1c116bc47 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -6,7 +6,7 @@ * Copyright (c) 1994, Regents of the University of California * * 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) pq_beginmessage(&buf); pq_sendbyte(&buf, 'A'); pq_sendint(&buf, listenerPID, sizeof(int32)); - pq_sendstring(&buf, relname, strlen(relname)); + pq_sendstring(&buf, 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 diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 06f55d648bc..ad6f045a944 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -15,7 +15,7 @@ * * 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 @@ * pq_sendbyte - append a raw byte to a StringInfo buffer * pq_sendint - append a binary integer 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_endmessage - send the completed message to the frontend * Note: it is also possible to append data to the StringInfo buffer using @@ -36,9 +36,8 @@ * Message input: * pq_getint - get an integer from connection * pq_getstr - get a null terminated string from connection - * pq_getnchar - get n characters from connection, and null-terminate - * pq_getstr and pq_getnchar perform MULTIBYTE conversion on the collected - * string. Use the raw pqcomm.c routines pq_getstring and pq_getbytes + * pq_getstr performs MULTIBYTE conversion on the collected string. + * Use the raw pqcomm.c routines pq_getstring or pq_getbytes * to fetch data without conversion. */ #include "postgres.h" @@ -48,6 +47,7 @@ #ifdef MULTIBYTE #include "mb/pg_wchar.h" #endif +#include <string.h> #ifdef HAVE_ENDIAN_H #include <endian.h> #endif @@ -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 caller to hand us the length (this is just because the caller - * usually knows the length anyway). In this routine, the data sent to - * the frontend is NOT null-terminated. + * The data sent to the frontend by this routine is a 4-byte count field + * (the count includes itself, by convention) followed by the string. + * The passed text string need not be null-terminated, and the data sent + * to the frontend isn't either. * -------------------------------- */ void -pq_sendtext(StringInfo buf, const char *str, int slen) +pq_sendcountedtext(StringInfo buf, const char *str, int slen) { #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 + pq_sendint(buf, slen + 4, 4); appendBinaryStringInfo(buf, str, slen); } /* -------------------------------- * pq_sendstring - append a null-terminated text string (with MULTIBYTE) * - * NB: passed text string must be null-terminated, even though we expect - * the caller to hand us the length (this is just because the caller - * usually knows the length anyway). + * NB: passed text string must be null-terminated, and so is the data + * sent to the frontend. * -------------------------------- */ void -pq_sendstring(StringInfo buf, const char *str, int slen) +pq_sendstring(StringInfo buf, const char *str) { + int slen = strlen(str); #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 appendBinaryStringInfo(buf, str, slen+1); } @@ -258,35 +271,18 @@ pq_getstr(char *s, int maxlen) c = pq_getstring(s, maxlen); #ifdef MULTIBYTE - p = (char*) pg_client_to_server((unsigned char *) s, maxlen); - if (s != p) /* actual conversion has been done? */ - strcpy(s, p); -#endif - - return c; -} - -/* -------------------------------- - * pq_getnchar - get n characters from connection, and null-terminate - * - * 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); + p = (char*) pg_client_to_server((unsigned char *) s, strlen(s)); + if (p != s) /* actual conversion has been done? */ + { + int newlen = strlen(p); + if (newlen < maxlen) + strcpy(s, p); + else + { + strncpy(s, p, maxlen); + s[maxlen-1] = '\0'; + } + } #endif return c; diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index d6f29aa8afc..26e04f5f855 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -7,7 +7,7 @@ * * * 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, for (i = 0; i < natts; ++i) { - pq_sendstring(&buf, attrs[i]->attname.data, - strlen(attrs[i]->attname.data)); + pq_sendstring(&buf, attrs[i]->attname.data); pq_sendint(&buf, (int) attrs[i]->atttypid, sizeof(attrs[i]->atttypid)); pq_sendint(&buf, attrs[i]->attlen, diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h index 2fe48539a2d..6404583a103 100644 --- a/src/include/libpq/pqformat.h +++ b/src/include/libpq/pqformat.h @@ -5,7 +5,7 @@ * * 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 @@ extern void pq_sendbyte(StringInfo buf, int byt); 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_sendstring(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); extern void pq_sendint(StringInfo buf, int i, int b); extern void pq_endmessage(StringInfo buf); extern int pq_getint(int *result, int b); extern int pq_getstr(char *s, int maxlen); -extern int pq_getnchar(char *s, int len); #endif /* PQFORMAT_H */ -- GitLab