Use a cursor for fetching data in -d or -D mode, so that pg_dump doesn't
run out of memory with large tables in these modes. Patch from Martijn van Oosterhout.
This commit is contained in:
parent
545c6696a6
commit
814f40cf43
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.226 2001/08/27 01:09:59 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.227 2001/08/27 20:33:07 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -400,77 +400,105 @@ dumpClasses_dumpData(Archive *fout, char *oid, void *dctxv)
|
|||||||
|
|
||||||
if (fout->remoteVersion >= 70100)
|
if (fout->remoteVersion >= 70100)
|
||||||
{
|
{
|
||||||
appendPQExpBuffer(q, "SELECT * FROM ONLY %s", fmtId(classname, force_quotes));
|
appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT * FROM ONLY %s", fmtId(classname, force_quotes));
|
||||||
} else {
|
} else {
|
||||||
appendPQExpBuffer(q, "SELECT * FROM %s", fmtId(classname, force_quotes));
|
appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT * FROM %s", fmtId(classname, force_quotes));
|
||||||
}
|
}
|
||||||
|
|
||||||
res = PQexec(g_conn, q->data);
|
res = PQexec(g_conn, q->data);
|
||||||
if (!res ||
|
if (!res ||
|
||||||
PQresultStatus(res) != PGRES_TUPLES_OK)
|
PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
{
|
{
|
||||||
write_msg(NULL, "dumpClasses(): SQL command failed\n");
|
write_msg(NULL, "dumpClasses(): SQL command failed\n");
|
||||||
write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
|
write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
|
||||||
write_msg(NULL, "The command was: %s\n", q->data);
|
write_msg(NULL, "The command was: %s\n", q->data);
|
||||||
exit_nicely();
|
exit_nicely();
|
||||||
}
|
}
|
||||||
for (tuple = 0; tuple < PQntuples(res); tuple++)
|
|
||||||
{
|
do {
|
||||||
archprintf(fout, "INSERT INTO %s ", fmtId(classname, force_quotes));
|
PQclear(res);
|
||||||
if (attrNames == true)
|
|
||||||
|
res = PQexec(g_conn, "FETCH 100 FROM _pg_dump_cursor");
|
||||||
|
if (!res ||
|
||||||
|
PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
{
|
{
|
||||||
resetPQExpBuffer(q);
|
write_msg(NULL, "dumpClasses(): SQL command failed\n");
|
||||||
appendPQExpBuffer(q, "(");
|
write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
|
||||||
|
write_msg(NULL, "The command was: FETCH 100 FROM _pg_dump_cursor\n");
|
||||||
|
exit_nicely();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tuple = 0; tuple < PQntuples(res); tuple++)
|
||||||
|
{
|
||||||
|
archprintf(fout, "INSERT INTO %s ", fmtId(classname, force_quotes));
|
||||||
|
if (attrNames == true)
|
||||||
|
{
|
||||||
|
resetPQExpBuffer(q);
|
||||||
|
appendPQExpBuffer(q, "(");
|
||||||
|
for (field = 0; field < PQnfields(res); field++)
|
||||||
|
{
|
||||||
|
if (field > 0)
|
||||||
|
appendPQExpBuffer(q, ",");
|
||||||
|
appendPQExpBuffer(q, fmtId(PQfname(res, field), force_quotes));
|
||||||
|
}
|
||||||
|
appendPQExpBuffer(q, ") ");
|
||||||
|
archprintf(fout, "%s", q->data);
|
||||||
|
}
|
||||||
|
archprintf(fout, "VALUES (");
|
||||||
for (field = 0; field < PQnfields(res); field++)
|
for (field = 0; field < PQnfields(res); field++)
|
||||||
{
|
{
|
||||||
if (field > 0)
|
if (field > 0)
|
||||||
appendPQExpBuffer(q, ",");
|
archprintf(fout, ",");
|
||||||
appendPQExpBuffer(q, fmtId(PQfname(res, field), force_quotes));
|
if (PQgetisnull(res, tuple, field))
|
||||||
|
{
|
||||||
|
archprintf(fout, "NULL");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (PQftype(res, field))
|
||||||
|
{
|
||||||
|
case INT2OID:
|
||||||
|
case INT4OID:
|
||||||
|
case OIDOID: /* int types */
|
||||||
|
case FLOAT4OID:
|
||||||
|
case FLOAT8OID:/* float types */
|
||||||
|
/* These types are printed without quotes */
|
||||||
|
archprintf(fout, "%s",
|
||||||
|
PQgetvalue(res, tuple, field));
|
||||||
|
break;
|
||||||
|
case BITOID:
|
||||||
|
case VARBITOID:
|
||||||
|
archprintf(fout, "B'%s'",
|
||||||
|
PQgetvalue(res, tuple, field));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All other types are printed as string literals,
|
||||||
|
* with appropriate escaping of special characters.
|
||||||
|
*/
|
||||||
|
resetPQExpBuffer(q);
|
||||||
|
formatStringLiteral(q, PQgetvalue(res, tuple, field), CONV_ALL);
|
||||||
|
archprintf(fout, "%s", q->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
appendPQExpBuffer(q, ") ");
|
archprintf(fout, ");\n");
|
||||||
archprintf(fout, "%s", q->data);
|
|
||||||
}
|
}
|
||||||
archprintf(fout, "VALUES (");
|
|
||||||
for (field = 0; field < PQnfields(res); field++)
|
|
||||||
{
|
|
||||||
if (field > 0)
|
|
||||||
archprintf(fout, ",");
|
|
||||||
if (PQgetisnull(res, tuple, field))
|
|
||||||
{
|
|
||||||
archprintf(fout, "NULL");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (PQftype(res, field))
|
|
||||||
{
|
|
||||||
case INT2OID:
|
|
||||||
case INT4OID:
|
|
||||||
case OIDOID: /* int types */
|
|
||||||
case FLOAT4OID:
|
|
||||||
case FLOAT8OID:/* float types */
|
|
||||||
/* These types are printed without quotes */
|
|
||||||
archprintf(fout, "%s",
|
|
||||||
PQgetvalue(res, tuple, field));
|
|
||||||
break;
|
|
||||||
case BITOID:
|
|
||||||
case VARBITOID:
|
|
||||||
archprintf(fout, "B'%s'",
|
|
||||||
PQgetvalue(res, tuple, field));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
/*
|
} while( PQntuples(res) > 0 );
|
||||||
* All other types are printed as string literals,
|
PQclear(res);
|
||||||
* with appropriate escaping of special characters.
|
|
||||||
*/
|
res = PQexec(g_conn, "CLOSE _pg_dump_cursor");
|
||||||
resetPQExpBuffer(q);
|
if (!res ||
|
||||||
formatStringLiteral(q, PQgetvalue(res, tuple, field), CONV_ALL);
|
PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||||
archprintf(fout, "%s", q->data);
|
{
|
||||||
break;
|
write_msg(NULL, "dumpClasses(): SQL command failed\n");
|
||||||
}
|
write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
|
||||||
}
|
write_msg(NULL, "The command was: CLOSE _pg_dump_cursor\n");
|
||||||
archprintf(fout, ");\n");
|
exit_nicely();
|
||||||
}
|
}
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
|
|
||||||
destroyPQExpBuffer(q);
|
destroyPQExpBuffer(q);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user