Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Microsoft.Data.Sqlite.Core/SqliteDataRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ public virtual Stream GetStream(int ordinal)
var blobDatabaseName = sqlite3_column_database_name(Handle, ordinal).utf8_to_string();
var blobTableName = sqlite3_column_table_name(Handle, ordinal).utf8_to_string();

if (blobDatabaseName == null
|| blobTableName == null)
{
// The value came from an expression, so there is no row to open a blob on. Looking for a rowid
// column would also hand these nulls to sqlite3_table_column_metadata, which is misuse
return new MemoryStream(GetCachedBlob(ordinal), false);
}

var rowidkey = $"{blobDatabaseName}_{blobTableName}";
if (!RowIds.TryGetValue(rowidkey, out var rowIdForOrdinal))
{
Expand Down
62 changes: 62 additions & 0 deletions test/Microsoft.Data.Sqlite.Tests/SqliteDataReaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,68 @@ public void GetStream_Blob_works(string createTableCmd, string selectCmd)
Assert.Equal([0x01, 0x02, 0x03, 0x04], buffer);
}

[Fact]
public void GetStream_works_when_expression_and_a_literal_in_the_same_query()
{
using var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();

connection.ExecuteNonQuery(
"CREATE TABLE DataTable (Id INTEGER PRIMARY KEY, Data BLOB); INSERT INTO DataTable VALUES (5, X'01020304');");

var selectCommand = connection.CreateCommand();
selectCommand.CommandText = "SELECT 42, substr(Data, 1, 3) FROM DataTable WHERE Id = 5";
using var reader = selectCommand.ExecuteReader();
Assert.True(reader.Read());

using var sourceStream = reader.GetStream(1);
Assert.IsType<MemoryStream>(sourceStream);
var buffer = new byte[3];
var bytesRead = sourceStream.Read(buffer, 0, 3);
Assert.Equal(3, bytesRead);
Assert.Equal([0x01, 0x02, 0x03], buffer);
}

[Fact]
public void GetTextReader_works_when_expression_and_a_literal_in_the_same_query()
{
using var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();

connection.ExecuteNonQuery(
"CREATE TABLE DataTable (Id INTEGER PRIMARY KEY, Value TEXT); INSERT INTO DataTable VALUES (5, 'abcdef');");

var selectCommand = connection.CreateCommand();
selectCommand.CommandText = "SELECT 42, substr(Value, 1, 3) FROM DataTable WHERE Id = 5";
using var reader = selectCommand.ExecuteReader();
Assert.True(reader.Read());

using var textReader = reader.GetTextReader(1);
Assert.Equal("abc", textReader.ReadToEnd());
}

[Fact]
public void GetStream_Blob_works_when_a_literal_is_in_the_same_query()
{
using var connection = new SqliteConnection("Data Source=:memory:");
connection.Open();

connection.ExecuteNonQuery(
"CREATE TABLE DataTable (Id INTEGER PRIMARY KEY, Data BLOB); INSERT INTO DataTable VALUES (5, X'01020304');");

var selectCommand = connection.CreateCommand();
selectCommand.CommandText = "SELECT 42, Id, Data FROM DataTable WHERE Id = 5";
using var reader = selectCommand.ExecuteReader();
Assert.True(reader.Read());

using var sourceStream = reader.GetStream(2);
Assert.IsType<SqliteBlob>(sourceStream);
var buffer = new byte[4];
var bytesRead = sourceStream.Read(buffer, 0, 4);
Assert.Equal(4, bytesRead);
Assert.Equal([0x01, 0x02, 0x03, 0x04], buffer);
}

[Fact]
public void GetStream_Blob_works_when_long_pk()
{
Expand Down
Loading