diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 769058d..0659d8e 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -1550,6 +1550,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) TableInfo *tbinfo = tdinfo->tdtable; const char *classname = tbinfo->dobj.name; PQExpBuffer q = createPQExpBuffer(); + PQExpBuffer staticStmt = NULL; PGresult *res; int tuple; int nfields; @@ -1591,34 +1592,55 @@ dumpTableData_insert(Archive *fout, void *dcontext) nfields = PQnfields(res); for (tuple = 0; tuple < PQntuples(res); tuple++) { - archprintf(fout, "INSERT INTO %s ", fmtId(classname)); - if (nfields == 0) + /* + * On first loop we build as much of the INSERT statment + * as possible. If the table happens to have 0 columns + * then this will be a complete statement, otherwise + * it will end in "VALUES(" and be ready to have the + * row's column values written. + */ + if (staticStmt == NULL) { + staticStmt = createPQExpBuffer(); + appendPQExpBuffer(staticStmt, "INSERT INTO %s ", fmtId(classname)); + /* corner case for zero-column table */ - archprintf(fout, "DEFAULT VALUES;\n"); - continue; - } - if (column_inserts) - { - resetPQExpBuffer(q); - appendPQExpBuffer(q, "("); - for (field = 0; field < nfields; field++) + if (nfields == 0) { - if (field > 0) - appendPQExpBuffer(q, ", "); - appendPQExpBufferStr(q, fmtId(PQfname(res, field))); + appendPQExpBufferStr(staticStmt, "DEFAULT VALUES;\n"); + } + else + { + if (column_inserts) + { + /* append the list of column names if required */ + appendPQExpBufferStr(staticStmt, "("); + for (field = 0; field < nfields; field++) + { + if (field > 0) + appendPQExpBufferStr(staticStmt, ", "); + appendPQExpBufferStr(staticStmt, fmtId(PQfname(res, field))); + } + appendPQExpBufferStr(staticStmt, ") "); + } + + appendPQExpBufferStr(staticStmt, "VALUES ("); } - appendPQExpBuffer(q, ") "); - archputs(q->data, fout); } - archprintf(fout, "VALUES ("); + + archputs(staticStmt->data, fout); + + /* if it is 0 column table then skip to the next row */ + if (nfields == 0) + continue; + for (field = 0; field < nfields; field++) { if (field > 0) - archprintf(fout, ", "); + archputs(", ", fout); if (PQgetisnull(res, tuple, field)) { - archprintf(fout, "NULL"); + archputs("NULL", fout); continue; } @@ -1647,7 +1669,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) const char *s = PQgetvalue(res, tuple, field); if (strspn(s, "0123456789 +-eE.") == strlen(s)) - archprintf(fout, "%s", s); + archputs(s, fout); else archprintf(fout, "'%s'", s); } @@ -1661,9 +1683,9 @@ dumpTableData_insert(Archive *fout, void *dcontext) case BOOLOID: if (strcmp(PQgetvalue(res, tuple, field), "t") == 0) - archprintf(fout, "true"); + archputs("true", fout); else - archprintf(fout, "false"); + archputs("false", fout); break; default: @@ -1676,7 +1698,7 @@ dumpTableData_insert(Archive *fout, void *dcontext) break; } } - archprintf(fout, ");\n"); + archputs(");\n", fout); } if (PQntuples(res) <= 0) @@ -1687,11 +1709,15 @@ dumpTableData_insert(Archive *fout, void *dcontext) PQclear(res); } - archprintf(fout, "\n\n"); + archputs("\n\n", fout); ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor"); destroyPQExpBuffer(q); + + if (staticStmt != NULL) + destroyPQExpBuffer(staticStmt); + return 1; }