Skip to content

Commit 09e27ff

Browse files
committed
count rows produced instead of getRow() in printRecords(ResultSet)
1 parent 8379c94 commit 09e27ff

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/main/java/org/apache/commons/csv/CSVPrinter.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,11 @@ public void printRecords(final Object... values) throws IOException {
502502
*/
503503
public void printRecords(final ResultSet resultSet) throws SQLException, IOException {
504504
final int columnCount = resultSet.getMetaData().getColumnCount();
505-
while (resultSet.next() && format.useRow(resultSet.getRow())) {
505+
// Count the rows produced here instead of ResultSet.getRow(): getRow() is the absolute cursor
506+
// position, which is optional for TYPE_FORWARD_ONLY result sets and returns 0 there, silently
507+
// disabling maxRows. Mirrors the row-produced counter the parser uses (CSV-327).
508+
long rowCount = 0;
509+
while (format.useRow(rowCount + 1) && resultSet.next()) {
506510
lock.lock();
507511
try {
508512
for (int i = 1; i <= columnCount; i++) {
@@ -523,6 +527,7 @@ public void printRecords(final ResultSet resultSet) throws SQLException, IOExcep
523527
} finally {
524528
lock.unlock();
525529
}
530+
rowCount++;
526531
}
527532
}
528533

src/test/java/org/apache/commons/csv/CSVPrinterTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.sql.ResultSet;
5252
import java.sql.SQLException;
5353
import java.sql.Statement;
54+
import java.sql.Types;
5455
import java.util.Arrays;
5556
import java.util.Date;
5657
import java.util.HashSet;
@@ -964,6 +965,30 @@ void testJdbcPrinterWithResultSetMetaData(final long maxRows) throws IOException
964965
}
965966
}
966967

968+
@Test
969+
void testJdbcPrinterWithResultSetWithoutRowNumber() throws IOException, SQLException {
970+
// JDBC makes ResultSet.getRow() optional for TYPE_FORWARD_ONLY result sets, where a driver may return 0.
971+
// maxRows must still cap the output by rows produced rather than by getRow().
972+
final StringWriter sw = new StringWriter();
973+
final CSVFormat format = CSVFormat.DEFAULT.builder().setMaxRows(2).get();
974+
try (SimpleResultSet resultSet = new SimpleResultSet() {
975+
@Override
976+
public int getRow() {
977+
return 0;
978+
}
979+
}) {
980+
resultSet.addColumn("ID", Types.INTEGER, 10, 0);
981+
for (int i = 1; i <= 4; i++) {
982+
resultSet.addRow(i);
983+
}
984+
try (CSVPrinter printer = new CSVPrinter(sw, format)) {
985+
printer.printRecords(resultSet);
986+
assertEquals(2, printer.getRecordCount());
987+
}
988+
}
989+
assertEquals("1" + RECORD_SEPARATOR + "2" + RECORD_SEPARATOR, sw.toString());
990+
}
991+
967992
@Test
968993
void testJira135_part1() throws IOException {
969994
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote(DQUOTE_CHAR).withEscape(BACKSLASH);

0 commit comments

Comments
 (0)