SCM

[#1010567] failed LargeObject operation causes NotSupportedException

View Trackers | Bugs | Download .csv | Monitor

Date:
2009-03-02 00:58
Priority:
3
State:
Open
Submitted by:
Rainer Mager (qythyx)
Assigned to:
Nobody (None)
Npgsql Version:
2.0
Category:
Group:
Resolution:
None
Summary:
failed LargeObject operation causes NotSupportedException

Detailed description
Here's a simple repro of the problem I'm seeing. It's a little convoluted so I'll explain.

First, this problem is set off whenever there is a failed operation with a LargeObject. This can be as simple as opening an unfound id (as in the first example below). This manifestation of the problem is mentioned at comments *1*, *2*, and *3*. All three of these cases happen, seemingly randomly. I sometimes have to re-run this test a number of times to get all three failures, but eventually they happen.

---REPRO 1---
[TestMethod()]
public void NpgsqlErrorRepro1()
{
using(NpgsqlConnection connection = new NpgsqlConnection(_ConnectionString))
{
connection.Open();
using(NpgsqlTransaction transaction = connection.BeginTransaction())
{
LargeObjectManager largeObjectMgr = new LargeObjectManager(connection);
try
{
LargeObject largeObject = largeObjectMgr.Open(-1, LargeObjectManager.READWRITE);
transaction.Commit();
}
catch
{
// ignore the LO failure
}
} // *1* sometimes it throws "System.NotSupportedException: This stream does not support seek operations"

using(NpgsqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM pg_database";
using(NpgsqlDataReader reader = command.ExecuteReader())
{
Assert.IsTrue(reader.Read()); // *2* this fails if the initial connection is used
}
}
} // *3* sometimes it throws "System.NotSupportedException: This stream does not support seek operations"
}
---END REPRO 1---


After discovering this issue I tried the following work-around, which revealed more information about the issue. Again the failure is documented at comment *1*. As it says, apparently if the "bad" connection from the failed LO operation is retrieved from the pool for the next operation then it is not in a good state. In this case the exception is "System.IndexOutOfRangeException: Field not found", but that's because the query is returning something like "select testSelect" (I forget the actual text) and not my real query. Since I was using the string index notation instead of a numerical ordinal this confused the hell out of me for a while.

My eventual fix was to add a connection.ClearPool() to the end of the main LO failure catch statement (after the connection.Dispose() block).


---REPRO 2---
[TestMethod()]
public void NpgsqlErrorRepro2()
{
NpgsqlConnection connection = new NpgsqlConnection(_ConnectionString);
connection.Open();
NpgsqlTransaction transaction = connection.BeginTransaction();
LargeObjectManager largeObjectMgr = new LargeObjectManager(connection);
try
{
LargeObject largeObject = largeObjectMgr.Open(-1, LargeObjectManager.READWRITE);
transaction.Commit();
}
catch
{
// ignore the LO failure
try
{
transaction.Dispose();
}
catch
{
// ignore dispose failure
}
try
{
connection.Dispose();
}
catch
{
// ignore dispose failure
}
}

using(connection = new NpgsqlConnection(_ConnectionString))
{
connection.Open();
using(NpgsqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM pg_database";
using(NpgsqlDataReader reader = command.ExecuteReader())
{
Assert.IsTrue(reader.Read());
// *1* this fails if the connection for the pool happens to be the bad one from above
Assert.IsTrue(!String.IsNullOrEmpty((string)reader["datname"]));
}
}
}
}
---END REPRO 2---

Followup

Message
Date: 2009-03-19 19:42
Sender: Francisco Figueiredo jr.


Hi, Rainer!

The problem is that largeobject api isn't handling errors correctly. It is letting some data in the stream.

On fix I could see right now for your problem was to add a call to Flush inside the method:
NpgsqlQuery.WriteToStream().

I hope it helps.

Attached Files:

Changes:

No Changes Have Been Made to This Item

Powered By FusionForge