PgFoundry Logo
     Advanced search
Log In
New Account
  
 
Home My Page Project Tree Project Openings Npgsql .Net Data Provider for Postgresql
 
 
 
 
Summary Forums Tracker Lists Tasks Docs Surveys News SCM Files
 
 

Bugs: Browse | Admin

[#1010567] failed LargeObject operation causes NotSupportedException

Date:
2009-03-02 00:58
Priority:
3
Submitted By:
Rainer Mager (qythyx)
Assigned To:
Nobody (None)
Category:
None
State:
Open
Npgsql Version:
 
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---

Please login

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:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item