Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EndOfStream exception when fetching query in DataTable using DbDataAdapter. #747

Closed
FransBouma opened this issue Sep 3, 2015 · 19 comments
Closed
Assignees
Labels
Milestone

Comments

@FransBouma
Copy link
Contributor

See: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=133091&ThreadID=23469

So, basically we execute:

SELECT  c.conname AS constraint_name, pkn.nspname AS pk_schema, fkn.nspname AS fk_schema, 
        fkt.relname AS fk_table, pkt.relname AS pk_table, pkf.attname AS pk_field, fkf.attname AS fk_field, 
        c.confkey AS pk_field_ordinals, c.conkey AS fk_field_ordinals, pkf.attnum AS pk_field_ordinal, 
        fkf.attnum AS fk_field_ordinal, c.confupdtype AS fk_update_rule, c.confdeltype AS fk_delete_rule 
FROM pg_constraint c 
    INNER JOIN pg_namespace n ON c.connamespace = n.oid 
    INNER JOIN pg_class pkt ON c.confrelid=pkt.oid 
    INNER JOIN pg_namespace pkn ON pkt.relnamespace = pkn.oid 
    INNER JOIN pg_class fkt ON c.conrelid=fkt.oid 
    INNER JOIN pg_namespace fkn ON fkt.relnamespace = fkn.oid 
    INNER JOIN pg_attribute pkf ON pkf.attnum = ANY(c.confkey) AND pkf.attrelid = pkt.oid 
    INNER JOIN pg_attribute fkf ON fkf.attnum = ANY(c.conkey) AND fkf.attrelid = fkt.oid 
WHERE c.contype='f' ORDER BY fk_schema ASC, fk_table ASC, constraint_name ASC, fk_field ASC, pk_schema ASC

using:

DbDataAdapter adapter = this.DriverToUse.CreateDataAdapter(query);
DataTable fkConstraints = new DataTable();
adapter.Fill( fkConstraints );

where query is the query as a normal string, and CreateDataAdapter creates using the DbProviderFactory a DbDataAdapter with a select command and a properly setup connection.

gives:

Exception type: EndOfStreamException
в Npgsql.NpgsqlBuffer.Ensure(Int32 count)
в Npgsql.TypeHandler.Read[T](NpgsqlBuffer buf, Int32 len, FieldDescription fieldDescription)
в Npgsql.TypeHandler.Read[T](DataRowMessage row, Int32 len, FieldDescription fieldDescription)
в Npgsql.TypeHandler`1.ReadValueAsObject(DataRowMessage row, FieldDescription fieldDescription)
в Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
в Npgsql.NpgsqlDataReader.GetValues(Object[] values)
в System.Data.ProviderBase.SchemaMapping.LoadDataRow()
в System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping)
в System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
в System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
в System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
в System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
в System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
в SD.LLBLGen.Pro.DBDrivers.PostgreSql.PostgreSqlCatalogRetriever.RetrieveForeignKeys(DBCatalog catalogMetaData)
в SD.LLBLGen.Pro.DBDrivers.PostgreSql.PostgreSqlCatalogRetriever.<ProduceAdditionalActionsToPerform>b__5(DBCatalog catalog)
в SD.LLBLGen.Pro.DBDriverCore.DBCatalogRetriever.PerformAdditionalActions(String catalogName, DBCatalog catalogMetaData, IEnumerable`1 actionsToPerform)
в SD.LLBLGen.Pro.DBDriverCore.DBCatalogRetriever.RetrieveCatalog(String catalogName, List`1 elementsToRetrieve)
в SD.LLBLGen.Pro.DBDriverCore.DBDriverBase.PopulateCatalogs(Dictionary`2 callBacks, Dictionary`2 elementsToRetrieve)
в SD.LLBLGen.Pro.Gui.Classes.GuiController.ObtainMetaDataFromDatabase(DBDriverBase driverUsed, Dictionary`2 selectedElements)
@roji roji self-assigned this Sep 3, 2015
@roji roji added the bug label Sep 3, 2015
@roji roji added this to the 3.0.2 milestone Sep 3, 2015
@roji
Copy link
Member

roji commented Sep 3, 2015

Hey @FransBouma.

The stack trace definitely points at an Npgsql bug. However, I just tried to reproduce the issue with the code above and didn't manage to. Below is the precise code I'm using (against 3.0.1), can you try to produce a repro?

using (var conn = new NpgsqlConnection(ConnectionString))
{
    var query = @"SELECT  c.conname AS constraint_name, pkn.nspname AS pk_schema, fkn.nspname AS fk_schema,
fkt.relname AS fk_table, pkt.relname AS pk_table, pkf.attname AS pk_field, fkf.attname AS fk_field,
c.confkey AS pk_field_ordinals, c.conkey AS fk_field_ordinals, pkf.attnum AS pk_field_ordinal,
fkf.attnum AS fk_field_ordinal, c.confupdtype AS fk_update_rule, c.confdeltype AS fk_delete_rule
FROM pg_constraint c
INNER JOIN pg_namespace n ON c.connamespace = n.oid
INNER JOIN pg_class pkt ON c.confrelid=pkt.oid
INNER JOIN pg_namespace pkn ON pkt.relnamespace = pkn.oid
INNER JOIN pg_class fkt ON c.conrelid=fkt.oid
INNER JOIN pg_namespace fkn ON fkt.relnamespace = fkn.oid
INNER JOIN pg_attribute pkf ON pkf.attnum = ANY(c.confkey) AND pkf.attrelid = pkt.oid
INNER JOIN pg_attribute fkf ON fkf.attnum = ANY(c.conkey) AND fkf.attrelid = fkt.oid
WHERE c.contype='f' ORDER BY fk_schema ASC, fk_table ASC, constraint_name ASC, fk_field ASC, pk_schema ASC
";
    var selectCommand = new NpgsqlCommand(query, conn);
    var adapter = new NpgsqlDataAdapter(selectCommand);
    var fkConstraints = new DataTable();
    adapter.Fill(fkConstraints);
}

@FransBouma
Copy link
Contributor Author

Did you have a table with a self-reference? This table fails:

CREATE TABLE public.Job
(
    Id bigint NOT NULL DEFAULT new_id() PRIMARY KEY,
    TypeFk bigint NOT NULL REFERENCES public.JobType,
    ParentJobFk bigint REFERENCES public.Job,
    ExecMethod varchar(250),
    Arguments text,
    Status varchar(50) NOT NULL,
    Comment varchar(500),
    Created timestamp NOT NULL DEFAULT utcnow(),
    Modified timestamp NOT NULL DEFAULT utcnow()
);

@roji
Copy link
Member

roji commented Sep 3, 2015

I do now, see code below. It's hard to imagine the self-reference being part of the problem - at the end of the day Npgsql just reads columns and rows from the big join query...

using (var conn = new NpgsqlConnection(ConnectionString))
{
    ExecuteNonQuery(@"DROP TABLE IF EXISTS public.""Job""");
    ExecuteNonQuery(@"DROP TABLE IF EXISTS public.""JobType""");
    ExecuteNonQuery(@"CREATE TABLE public.""JobType"" (Id BIGSERIAL NOT NULL PRIMARY KEY)");
    ExecuteNonQuery(@"CREATE TABLE public.""Job""
(
Id BIGSERIAL NOT NULL PRIMARY KEY,
TypeFk bigint NOT NULL REFERENCES public.""JobType"",
ParentJobFk bigint REFERENCES public.""Job"",
ExecMethod varchar(250),
Arguments text,
Status varchar(50) NOT NULL,
Comment varchar(500),
Created timestamp,
Modified timestamp
);");

    var query = @"SELECT  c.conname AS constraint_name, pkn.nspname AS pk_schema, fkn.nspname AS fk_schema,
fkt.relname AS fk_table, pkt.relname AS pk_table, pkf.attname AS pk_field, fkf.attname AS fk_field,
c.confkey AS pk_field_ordinals, c.conkey AS fk_field_ordinals, pkf.attnum AS pk_field_ordinal,
fkf.attnum AS fk_field_ordinal, c.confupdtype AS fk_update_rule, c.confdeltype AS fk_delete_rule
FROM pg_constraint c
INNER JOIN pg_namespace n ON c.connamespace = n.oid
INNER JOIN pg_class pkt ON c.confrelid=pkt.oid
INNER JOIN pg_namespace pkn ON pkt.relnamespace = pkn.oid
INNER JOIN pg_class fkt ON c.conrelid=fkt.oid
INNER JOIN pg_namespace fkn ON fkt.relnamespace = fkn.oid
INNER JOIN pg_attribute pkf ON pkf.attnum = ANY(c.confkey) AND pkf.attrelid = pkt.oid
INNER JOIN pg_attribute fkf ON fkf.attnum = ANY(c.conkey) AND fkf.attrelid = fkt.oid
WHERE c.contype='f' ORDER BY fk_schema ASC, fk_table ASC, constraint_name ASC, fk_field ASC, pk_schema ASC
";
    var selectCommand = new NpgsqlCommand(query, conn);
    var adapter = new NpgsqlDataAdapter(selectCommand);
    var fkConstraints = new DataTable();
    adapter.Fill(fkConstraints);
}

@roji
Copy link
Member

roji commented Sep 3, 2015

FYI I was thinking of publishing 3.0.2 very soon (e.g. tomorrow), I hope you guys can get a reliable repro quickly (there is obviously a bug to be fixed here)

@Emill
Copy link
Contributor

Emill commented Sep 3, 2015

Does the backend log say anything useful?

@FransBouma
Copy link
Contributor Author

I can test it tomorrow morning (CET) on our setup (a customer ran into it). I'll ask the customer to participate in this thread too, and to test your small repro.

One thing I was thinking about which might be the cause (but it's a bit far fetched) is whether it's caused by a timeout: if a timeout occurs, can this exception occur? I do know that a timeout sometimes causes a similar exception on ODP.NET (Oracle's ADO.NET provider) when data is streamed from the server to the client.

FYI I was thinking of publishing 3.0.2 very soon (e.g. tomorrow), I hope you guys can get a reliable
repro quickly (there is obviously a bug to be fixed here)


Reply to this email directly or view it on GitHub
#747 (comment) .
https://github.com/notifications/beacon/ADdd8pCh52KXXVEe3ax4c-Yz-HjrTeqCks5ouHaAgaJpZM4F3RUu.gif

@roji
Copy link
Member

roji commented Sep 3, 2015

Well, according to the stack trace Npgsql is trying to read data (in order to populate the values) but the backend has closed the connection. Like @Emill suggests it could be a good idea to look at the PostgreSQL logs. If PostgreSQL decided to close the connection because of a timeout, that would explain it (I think pgbouncer has an option like this).

So let's try to work on this tomorrow. I'm in Europe so I won't be up CET morning, but I think I'll be free in the afternoon if you and your client are still around.

@kae
Copy link

kae commented Sep 3, 2015

I have some exceptions at not mission critical production usage now (with 3.0.1)

That exception is more or less frequent with some state of query results, that I still can't reproduce in test environment, so I didn't report it before. This exception is thrown after timeout of statement (30 sec) and has backend log entry 'unexpected EOF on client connection with an open transaction'

System.Data.DataException: Error parsing column 7 (Offsets=fo - String) ---> System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at Npgsql.NpgsqlBuffer.Ensure(Int32 count)
   at Npgsql.TypeHandler.Read[T](NpgsqlBuffer buf, Int32 len, FieldDescription fieldDescription)
   at Npgsql.TypeHandler.Read[T](DataRowMessage row, Int32 len, FieldDescription fieldDescription)
   at Npgsql.TypeHandler`1.ReadValueAsObject(DataRowMessage row, FieldDescription fieldDescription)
   at Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
   at Npgsql.NpgsqlDataReader.get_Item(Int32 ordinal)
   at Deserializedf529d00-61a1-4dbb-b31a-df3a582407de(IDataReader )
   --- End of inner exception stack trace ---
   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value)
   at Deserializedf529d00-61a1-4dbb-b31a-df3a582407de(IDataReader )
   at Dapper.SqlMapper.<QueryAsync>d__147`1.MoveNext()

That exception is not so frequent, but I get it from same query and without any timeout

 System.Data.DataException: Error parsing column 7 (Offsets=fo - String) ---> System.IO.EndOfStreamException: Attempted to read past the end of the stream.
   at Npgsql.NpgsqlBuffer.Ensure(Int32 count)
   at Npgsql.TypeHandler.Read[T](NpgsqlBuffer buf, Int32 len, FieldDescription fieldDescription)
   at Npgsql.TypeHandler.Read[T](DataRowMessage row, Int32 len, FieldDescription fieldDescription)
   at Npgsql.TypeHandler`1.ReadValueAsObject(DataRowMessage row, FieldDescription fieldDescription)
   at Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
   at Npgsql.NpgsqlDataReader.get_Item(Int32 ordinal)
   at Deserialize30d751b8-8a47-424c-b3aa-163ed27919ac(IDataReader )
   --- End of inner exception stack trace ---
   at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value)
   at Deserialize30d751b8-8a47-424c-b3aa-163ed27919ac(IDataReader )
   at Dapper.SqlMapper.<QueryAsync>d__147`1.MoveNext()

I was hoping it was from array issues, that was fixed in 3.0.2
So if it will struck me tomorrow morning I will try new version and will report results.

@TheMidgardWatcher
Copy link

Hi, we are still around. I am that client, who submitted this bug. It's late right now (UTC +3), but tomorrow i'll look to the PostgreSQL logs. But i can say now, that i'm using port for fetching this query, that PostgreSQL listens directly. As for question that @roji was wrote about self-reference - it's definetly can be a reason, because in table, that @FransBouma have posted, when i dropping self-reference field - i was able to fetch this query without any errors.

@roji
Copy link
Member

roji commented Sep 3, 2015

@TheMidgardWatcher thanks for the extra info, I'll wait for more info tomorrow.

My point about the self-reference field is that it's not a direct cause, but it could definitely trigger the bug in some way. The best way forward is some sort of way I can reproduce the bug on my machine.

@roji
Copy link
Member

roji commented Sep 3, 2015

@kae, thanks for joining in, your experience definitely seems relevant. It could in theory arise from the array issues already fixed, you can install the 3.0.2-beta nuget from our unstable feed to test and confirm (@TheMidgardWatcher, this goes for you too if you're interested).

Sorry for the hassle this is causing, hopefully we'll resolve it quickly and release 3.0.2.

@TheMidgardWatcher
Copy link

@roji I'm unable to find 3.0.2-beta version of npgsql to test if this bug resolved there.

@roji
Copy link
Member

roji commented Sep 4, 2015

@TheMidgardWatcher you have to add the nuget unstable feed to see it: https://www.myget.org/F/npgsql-unstable. You can do this inside the GUI in Visual Studio (Tools -> NuGet Package Manager -> Package Manager Settings -> Package Sources), or you can add it to NuGet.config at the root of your project (https://docs.nuget.org/consume/nuget-config-file).

Let me know if you still have trouble.

@TheMidgardWatcher
Copy link

@roji Thanks! Just tested unstable version Npgsql.3.0.2-beta0027 - bug is not reproducing. I think my problem is solved - I'll wait stable release!

@roji
Copy link
Member

roji commented Sep 4, 2015

@TheMidgardWatcher, that would be really great news. Are you confident that the bug is gone, was it easy to reproduce before?

If so I'll release 3.0.2.

@TheMidgardWatcher
Copy link

Yes - it was easy to repoduce on our environment, and after i replaced npgsql 3.0.1 to 3.0.2-beta0027 - bug is gone. So with this version we can't reproduce it anymore!

@FransBouma
Copy link
Contributor Author

Trying to reproduce it, but I run into another problem:

The field data_type has a type currently unknown to Npgsql (OID 2206). You can retrieve it as a string by marking it as unknown, please see the FAQ.

Stacktrace:

 at Npgsql.NpgsqlDataReader.GetValue(Int32 ordinal)
   at Npgsql.NpgsqlDataReader.GetValues(Object[] values)
   at System.Data.ProviderBase.DataReaderContainer.CommonLanguageSubsetDataReader.GetValues(Object[] values)
   at System.Data.ProviderBase.SchemaMapping.LoadDataRow()
   at System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping)
   at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
   at SD.LLBLGen.Pro.DBDrivers.PostgreSql.PostgreSqlSchemaRetriever.RetrieveViewAndFieldMetaData(DBSchema schemaToFill, IEnumerable`1 elementNames) in c:\Myprojects\VS.NET Projects\LLBLGen Pro v4.2\Drivers\PostgreSql\PostgreSqlSchemaRetriever.cs:line 244

SQL:

SELECT  attname as column_name, attnum as ordinal_position, atttypid::regtype as data_type, 
        information_schema._pg_char_max_length(atttypid, atttypmod) as character_maximum_length, 
        information_schema._pg_char_octet_length(atttypid, atttypmod) as character_octet_length, 
        information_schema._pg_numeric_precision(atttypid, atttypmod) as numeric_precision, 
        information_schema._pg_numeric_precision_radix(atttypid, atttypmod) as numeric_precision_radix, 
        information_schema._pg_numeric_scale(atttypid, atttypmod) as numeric_scale 
FROM pg_attribute WHERE attrelid = ('public.'||:tableName)::regclass AND attnum > 0 AND NOT attisdropped

Where :tableName is customersmatview which looks like:

-- Materialized View: customersmatview
CREATE MATERIALIZED VIEW customersmatview AS 
 SELECT customers.customerid,
    customers.companyname,
    customers.contactname,
    customers.contacttitle,
    customers.address,
    customers.city,
    customers.region,
    customers.postalcode,
    customers.country,
    customers.phone,
    customers.fax
   FROM customers
WITH DATA;

ALTER TABLE customersmatview
  OWNER TO postgres;

which is defined on the Northwind Customers table. If I disable retrieving this, I can't reproduce the issue I started this thread with, I have the table which gives an issue in the DB (albeit without the fields with a default constraint). PG9.3, npgsql 3.0.1
2.2.1 works fine.

So TL;DR: original issue isn't reproducible here, but doing so I ran into another issue.

@roji
Copy link
Member

roji commented Sep 4, 2015

@FransBouma, this is because you're querying a relatively exotic type (regtype). Can you please open a separate issue for this, I'll take a look now if we can natively support it.

Otherwise closing this issue.

@roji roji closed this as completed Sep 4, 2015
@FransBouma
Copy link
Contributor Author

Will do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants