Skip to content

Commit 07c33ba

Browse files
committed
pg_dump -d or -D didn't quote special characters in INSERT data
correctly. -D had problems with tables with inherited fields, also.
1 parent 566c712 commit 07c33ba

File tree

1 file changed

+43
-50
lines changed

1 file changed

+43
-50
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
*
2323
* IDENTIFICATION
24-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.100 1999/01/21 22:53:36 momjian Exp $
24+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.101 1999/02/08 01:46:28 tgl Exp $
2525
*
2626
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
2727
*
@@ -321,51 +321,41 @@ static void
321321
dumpClasses_dumpData(FILE *fout, const char *classname,
322322
const TableInfo tblinfo, bool oids)
323323
{
324-
325324
PGresult *res;
326-
char query[255];
327-
int actual_atts; /* number of attrs in this a table */
328-
char expandbuf[COPYBUFSIZ];
329325
char q[MAXQUERYLEN];
330-
int tuple;
331-
int field;
326+
int tuple;
327+
int field;
328+
char *expsrc;
329+
char *expdest;
332330

333-
sprintf(query, "SELECT * FROM %s", fmtId(classname, force_quotes));
334-
res = PQexec(g_conn, query);
331+
sprintf(q, "SELECT * FROM %s", fmtId(classname, force_quotes));
332+
res = PQexec(g_conn, q);
335333
if (!res ||
336334
PQresultStatus(res) != PGRES_TUPLES_OK)
337335
{
338336
fprintf(stderr, "dumpClasses(): command failed\n");
339337
exit_nicely(g_conn);
340338
}
341-
tuple = 0;
342-
while (tuple < PQntuples(res))
339+
for (tuple = 0; tuple < PQntuples(res); tuple++)
343340
{
344341
fprintf(fout, "INSERT INTO %s ", fmtId(classname, force_quotes));
345342
if (attrNames)
346343
{
347-
int j;
348-
349-
actual_atts = 0;
350344
sprintf(q, "(");
351-
for (j = 0; j < tblinfo.numatts; j++)
345+
for (field = 0; field < PQnfields(res); field++)
352346
{
353-
if (tblinfo.inhAttrs[j] == 0)
354-
{
355-
sprintf(q, "%s%s%s",
356-
q,
357-
(actual_atts > 0) ? "," : "",
358-
fmtId(tblinfo.attnames[j], force_quotes));
359-
actual_atts++;
360-
}
347+
if (field > 0)
348+
strcat(q, ",");
349+
strcat(q, fmtId(PQfname(res, field), force_quotes));
361350
}
362-
sprintf(q, "%s%s", q, ") ");
363-
fprintf(fout, q);
351+
strcat(q, ") ");
352+
fprintf(fout, "%s", q);
364353
}
365354
fprintf(fout, "values (");
366-
field = 0;
367-
do
355+
for (field = 0; field < PQnfields(res); field++)
368356
{
357+
if (field > 0)
358+
fprintf(fout, ",");
369359
if (PQgetisnull(res, tuple, field))
370360
fprintf(fout, "NULL");
371361
else
@@ -377,41 +367,44 @@ dumpClasses_dumpData(FILE *fout, const char *classname,
377367
case OIDOID: /* int types */
378368
case FLOAT4OID:
379369
case FLOAT8OID: /* float types */
370+
/* These types are printed without quotes */
380371
fprintf(fout, "%s",
381372
PQgetvalue(res, tuple, field));
382373
break;
383374
default:
375+
/* All other types are printed as string literals,
376+
* with appropriate escaping of special characters.
377+
* Quote mark ' goes to '' per SQL standard,
378+
* other stuff goes to \ sequences.
379+
*/
380+
expsrc = PQgetvalue(res, tuple, field);
381+
expdest = q;
382+
for (; *expsrc; expsrc++)
384383
{
385-
char *expsrc,
386-
*expdest;
387-
388-
/*
389-
* Before outputting string value, expand all
390-
* single quotes to twin single quotes - dhb -
391-
* 6/11/96
392-
*/
393-
expsrc = PQgetvalue(res, tuple, field);
394-
expdest = expandbuf;
395-
while (*expsrc)
384+
char ch = *expsrc;
385+
if (ch == '\\' || ch == '\'')
396386
{
397-
*expdest++ = *expsrc;
398-
if (*expsrc == (char) 0x27) /* single quote */
399-
*expdest++ = *expsrc;
400-
expsrc++;
387+
*expdest++ = ch; /* double it */
388+
*expdest++ = ch;
401389
}
402-
*expdest = *expsrc; /* null term. */
403-
404-
fprintf(fout, "'%s'", expandbuf);
390+
else if (ch < '\040')
391+
{
392+
/* generate octal escape for control chars */
393+
*expdest++ = '\\';
394+
*expdest++ = ((ch >> 6) & 3) + '0';
395+
*expdest++ = ((ch >> 3) & 7) + '0';
396+
*expdest++ = (ch & 7) + '0';
397+
}
398+
else
399+
*expdest++ = ch;
405400
}
401+
*expdest = '\0';
402+
fprintf(fout, "'%s'", q);
406403
break;
407404
}
408405
}
409-
field++;
410-
if (field != PQnfields(res))
411-
fprintf(fout, ",");
412-
} while (field < PQnfields(res));
406+
}
413407
fprintf(fout, ");\n");
414-
tuple++;
415408
}
416409
PQclear(res);
417410
}

0 commit comments

Comments
 (0)