1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-18 17:41:14 +03:00

Fix updatable ResultSets stream methods (ascii, character, binary).

The existing code didn't correctly allocate data arrays, and it
failed to loop when a stream didn't provide the full amount of
data requested of it.

Reported by Jan de Visser.
This commit is contained in:
Kris Jurka 2004-06-21 02:01:12 +00:00
parent 3cec5b804d
commit 922c2638e4
6 changed files with 138 additions and 25 deletions

View File

@ -93,7 +93,6 @@ postgresql.updateable.emptydelete:Can't deleteRow() on empty result set
postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow(). postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow().
postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow().
postgresql.updateable.notoninsertrow:Not on insert row. postgresql.updateable.notoninsertrow:Not on insert row.
postgresql.updateable.inputstream:Input Stream is null.
postgresql.updateable.ioerror:Input Stream Error - {0} postgresql.updateable.ioerror:Input Stream Error - {0}
postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made. postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made.
postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments)

View File

@ -95,7 +95,6 @@ postgresql.updateable.emptydelete:N
postgresql.updateable.beforestartdelete:Antes do início do conjunto de resultados. Não pode chamar deleteRow(). postgresql.updateable.beforestartdelete:Antes do início do conjunto de resultados. Não pode chamar deleteRow().
postgresql.updateable.afterlastdelete:Depois do fim do conjunto de resultados. Não pode chamar deleteRow(). postgresql.updateable.afterlastdelete:Depois do fim do conjunto de resultados. Não pode chamar deleteRow().
postgresql.updateable.notoninsertrow:Não está inserindo um registro. postgresql.updateable.notoninsertrow:Não está inserindo um registro.
postgresql.updateable.inputstream:Fluxo de Entrada é nulo.
postgresql.updateable.ioerror:Erro de Fluxo de Entrada - {0} postgresql.updateable.ioerror:Erro de Fluxo de Entrada - {0}
postgresql.call.noreturntype:Uma Instrução Executável foi declarada mas nenhuma chamada a 'registerOutParameter (1, <algum_tipo>)' foi feita. postgresql.call.noreturntype:Uma Instrução Executável foi declarada mas nenhuma chamada a 'registerOutParameter (1, <algum_tipo>)' foi feita.
postgresql.call.noinout:PostgreSQL só suporta função que retorna valor [@ 1] (nenhum argumento OUT ou INOUT) postgresql.call.noinout:PostgreSQL só suporta função que retorna valor [@ 1] (nenhum argumento OUT ou INOUT)

View File

@ -99,7 +99,6 @@ postgresql.updateable.emptydelete:Can't deleteRow() on empty result set
postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow(). postgresql.updateable.beforestartdelete:Before start of result set. Can not call deleteRow().
postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow().
postgresql.updateable.notoninsertrow:Not on insert row. postgresql.updateable.notoninsertrow:Not on insert row.
postgresql.updateable.inputstream:Input Stream is null.
postgresql.updateable.ioerror:ошибка Input Stream - {0} postgresql.updateable.ioerror:ошибка Input Stream - {0}
postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made. postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)' was made.
postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments)

View File

@ -93,7 +93,6 @@ postgresql.updateable.emptydelete:\u4e0d\u884c\u5728\u7a7a\u7684ResultSet\u4f7f\
postgresql.updateable.beforestartdelete:\u4e0d\u884c\u5728ResultSet\u7684\u7b2c\u4e00\u7b46\u8cc7\u6599\u4e4b\u524d\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002 postgresql.updateable.beforestartdelete:\u4e0d\u884c\u5728ResultSet\u7684\u7b2c\u4e00\u7b46\u8cc7\u6599\u4e4b\u524d\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002
postgresql.updateable.afterlastdelete:\u4e0d\u884c\u5728ResultSet\u7684\u6700\u5f8c\u4e00\u7b46\u8cc7\u6599\u4e4b\u5f8c\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002 postgresql.updateable.afterlastdelete:\u4e0d\u884c\u5728ResultSet\u7684\u6700\u5f8c\u4e00\u7b46\u8cc7\u6599\u4e4b\u5f8c\u547c\u53ebdeleteRow()\u65b9\u6cd5\u3002
postgresql.updateable.notoninsertrow:\u4e0d\u5728\u65b0\u589e\u7684\u8cc7\u6599\u5217\u4e0a\u3002 postgresql.updateable.notoninsertrow:\u4e0d\u5728\u65b0\u589e\u7684\u8cc7\u6599\u5217\u4e0a\u3002
postgresql.updateable.inputstream:InputStream\u662fnull\u3002
postgresql.updateable.ioerror:InputStream\u932f\u8aa4\u3002 postgresql.updateable.ioerror:InputStream\u932f\u8aa4\u3002
postgresql.call.noreturntype:\u5df2\u7d93\u5ba3\u544aCallableStatement\u51fd\u5f0f\uff0c\u4f46\u662f\u5c1a\u672a\u547c\u53eb'registerOutParameter (1, <some_type>)'\u3002 postgresql.call.noreturntype:\u5df2\u7d93\u5ba3\u544aCallableStatement\u51fd\u5f0f\uff0c\u4f46\u662f\u5c1a\u672a\u547c\u53eb'registerOutParameter (1, <some_type>)'\u3002
postgresql.call.noinout:PostgreSQL\u53ea\u652f\u63f4\u50b3\u56de\u503c\u70ba[@ 1]\u7684\u51fd\u5f0f(\u6c92\u6709OUT\u6216INPUT\u5f15\u6578)\u3002 postgresql.call.noinout:PostgreSQL\u53ea\u652f\u63f4\u50b3\u56de\u503c\u70ba[@ 1]\u7684\u51fd\u5f0f(\u6c92\u6709OUT\u6216INPUT\u5f15\u6578)\u3002

View File

@ -9,7 +9,7 @@
* Copyright (c) 2003, PostgreSQL Global Development Group * Copyright (c) 2003, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.25.2.6 2004/06/16 05:11:44 jurka Exp $ * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.25.2.7 2004/06/21 02:01:11 jurka Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -18,6 +18,8 @@ package org.postgresql.jdbc2;
import java.io.CharArrayReader; import java.io.CharArrayReader;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.util.Enumeration; import java.util.Enumeration;
@ -210,6 +212,7 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
rowBuffer = new byte[this_row.length][]; rowBuffer = new byte[this_row.length][];
System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
onInsertRow = false;
return true; return true;
} }
@ -220,6 +223,8 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
final int rows_size = rows.size(); final int rows_size = rows.size();
if (rows_size > 0) if (rows_size > 0)
current_row = rows_size; current_row = rows_size;
onInsertRow = false;
} }
@ -227,6 +232,8 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
{ {
if (rows.size() > 0) if (rows.size() > 0)
current_row = -1; current_row = -1;
onInsertRow = false;
} }
@ -235,12 +242,12 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
if (rows.size() <= 0) if (rows.size() <= 0)
return false; return false;
onInsertRow = false;
current_row = 0; current_row = 0;
this_row = (byte[][]) rows.elementAt(current_row); this_row = (byte[][]) rows.elementAt(current_row);
rowBuffer = new byte[this_row.length][]; rowBuffer = new byte[this_row.length][];
System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
onInsertRow = false;
return true; return true;
} }
@ -483,6 +490,7 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
rowBuffer = new byte[this_row.length][]; rowBuffer = new byte[this_row.length][];
System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length); System.arraycopy(this_row, 0, rowBuffer, 0, this_row.length);
onInsertRow = false;
return true; return true;
} }
@ -762,21 +770,39 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
) )
throws SQLException throws SQLException
{ {
byte[] theData = null; if (x == null)
{
updateNull(columnIndex);
return;
}
try try
{ {
x.read(theData, 0, length); InputStreamReader reader = new InputStreamReader(x, "ASCII");
char data[] = new char[length];
int numRead = 0;
while (true)
{
int n = reader.read(data, numRead, length - numRead);
if (n == -1)
break;
numRead += n;
if (numRead == length)
break;
}
updateString(columnIndex, new String(data, 0, numRead));
} }
catch (NullPointerException ex ) catch (UnsupportedEncodingException uee)
{ {
throw new PSQLException("postgresql.updateable.inputstream"); throw new PSQLException("postgresql.unusual", PSQLState.UNEXPECTED_ERROR, uee);
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new PSQLException("postgresql.updateable.ioerror", ie); throw new PSQLException("postgresql.updateable.ioerror", ie);
} }
updateValue(columnIndex, theData);
} }
@ -794,21 +820,46 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
) )
throws SQLException throws SQLException
{ {
byte[] theData = null; if (x == null)
{
updateNull(columnIndex);
return;
}
byte data[] = new byte[length];
int numRead = 0;
try try
{ {
x.read(theData, 0, length); while (true)
{
int n = x.read(data, numRead, length - numRead);
if (n == -1)
break;
} numRead += n;
catch ( NullPointerException ex )
{ if (numRead == length)
throw new PSQLException("postgresql.updateable.inputstream"); break;
}
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new PSQLException("postgresql.updateable.ioerror", ie); throw new PSQLException("postgresql.updateable.ioerror", ie);
} }
updateValue(columnIndex, theData);
if (numRead == length)
{
updateBytes(columnIndex, data);
}
else
{
// the stream contained less data than they said
// perhaps this is an error?
byte data2[] = new byte[numRead];
System.arraycopy(data, 0, data2, 0, numRead);
updateBytes(columnIndex, data2);
}
} }
@ -841,21 +892,33 @@ public abstract class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.Abstra
) )
throws SQLException throws SQLException
{ {
char[] theData = null; if (x == null)
{
updateNull(columnIndex);
return;
}
try try
{ {
x.read(theData, 0, length); char data[] = new char[length];
int numRead = 0;
while (true)
{
int n = x.read(data, numRead, length - numRead);
if (n == -1)
break;
} numRead += n;
catch (NullPointerException ex)
{ if (numRead == length)
throw new PSQLException("postgresql.updateable.inputstream"); break;
}
updateString(columnIndex, new String(data, 0, numRead));
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new PSQLException("postgresql.updateable.ioerror", ie); throw new PSQLException("postgresql.updateable.ioerror", ie);
} }
updateValue(columnIndex, theData);
} }

View File

@ -3,6 +3,12 @@ package org.postgresql.test.jdbc2;
import java.sql.*; import java.sql.*;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import org.postgresql.test.TestUtil; import org.postgresql.test.TestUtil;
/** /**
* <p>Title: </p> * <p>Title: </p>
@ -27,6 +33,7 @@ public class UpdateableResultTest extends TestCase
con = TestUtil.openDB(); con = TestUtil.openDB();
TestUtil.createTable(con, "updateable", "id int primary key, name text, notselected text"); TestUtil.createTable(con, "updateable", "id int primary key, name text, notselected text");
TestUtil.createTable(con, "second", "id1 int primary key, name1 text"); TestUtil.createTable(con, "second", "id1 int primary key, name1 text");
TestUtil.createTable(con, "stream", "id int primary key, asi text, chr text, bin bytea");
// put some dummy data into second // put some dummy data into second
Statement st2 = con.createStatement(); Statement st2 = con.createStatement();
@ -39,6 +46,7 @@ public class UpdateableResultTest extends TestCase
{ {
TestUtil.dropTable(con, "updateable"); TestUtil.dropTable(con, "updateable");
TestUtil.dropTable(con, "second"); TestUtil.dropTable(con, "second");
TestUtil.dropTable(con, "stream");
TestUtil.closeDB(con); TestUtil.closeDB(con);
} }
@ -110,6 +118,52 @@ public class UpdateableResultTest extends TestCase
st.close(); st.close();
} }
public void testUpdateStreams() throws SQLException, UnsupportedEncodingException
{
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT id, asi, chr, bin FROM stream");
rs.moveToInsertRow();
rs.updateInt(1, 1);
rs.updateAsciiStream("asi", null, 17);
rs.updateCharacterStream("chr", null, 81);
rs.updateBinaryStream("bin", null, 0);
rs.insertRow();
rs.beforeFirst();
rs.next();
assertEquals(1, rs.getInt(1));
assertNull(rs.getString(2));
assertNull(rs.getString(3));
assertNull(rs.getBytes(4));
String string = "Hello";
InputStream asi = new ByteArrayInputStream(string.getBytes("US-ASCII"));
Reader chr = new StringReader(string);
InputStream bin = new ByteArrayInputStream(string.getBytes("US-ASCII"));
rs.updateInt("id", 2);
rs.updateAsciiStream("asi", asi, 5);
rs.updateCharacterStream("chr", chr, 5);
rs.updateBinaryStream("bin", bin, 5);
rs.updateRow();
assertEquals(2, rs.getInt(1));
assertEquals(string, rs.getString(2));
assertEquals(string, rs.getString(3));
assertEquals(string, rs.getString(4));
rs.refreshRow();
assertEquals(2, rs.getInt(1));
assertEquals(string, rs.getString(2));
assertEquals(string, rs.getString(3));
assertEquals(string, rs.getString(4));
rs.close();
stmt.close();
}
public void testUpdateable() throws SQLException public void testUpdateable() throws SQLException