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
9 changes: 7 additions & 2 deletions DuckDB.NET.Data/DuckDBDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,17 +305,22 @@ public override object GetProviderSpecificValue(int ordinal)

public override int GetValues(object[] values)
{
ArgumentNullException.ThrowIfNull(values);
CheckRowRead();

var offset = rowsReadFromCurrentChunk - 1;

for (var i = 0; i < FieldCount; i++)
// IDataRecord.GetValues: "You can pass an Object array that contains fewer than the number of columns that are
// contained in the resulting row. Only the amount of data the Object array holds is copied to the array."
var count = Math.Min(values.Length, FieldCount);

for (var i = 0; i < count; i++)
{
var reader = vectorReaders[i];
values[i] = reader.IsValid(offset) ? reader.GetValue(offset) : DBNull.Value;
}

return FieldCount;
return count;
}

public override Stream GetStream(int ordinal)
Expand Down
25 changes: 24 additions & 1 deletion DuckDB.NET.Test/DuckDBDataReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -843,5 +843,28 @@ public void GetOrdinalThrowsIndexOutOfRangeForAnUnknownName()

reader.Invoking(r => r.GetOrdinal("missing")).Should().Throw<IndexOutOfRangeException>();
}
}

// https://learn.microsoft.com/dotnet/api/system.data.idatarecord.getvalues: "You can pass an Object array that
// contains fewer than the number of columns that are contained in the resulting row. Only the amount of data the
// Object array holds is copied to the array. You can also pass an Object array whose length is more than the
// number of columns that are contained in the resulting row."
[Fact]
public void GetValuesCopiesOnlyWhatTheArrayHolds()
{
Command.CommandText = "SELECT 1 AS a, 2 AS b, 3 AS c";
using var reader = Command.ExecuteReader();
reader.Read().Should().BeTrue();

reader.GetValues(new object[0]).Should().Be(0);
reader.Invoking(r => r.GetValues(null!)).Should().Throw<ArgumentNullException>();

var shorter = new object[2];
reader.GetValues(shorter).Should().Be(2);
shorter.Should().Equal(1, 2);

var longer = new object[5];
reader.GetValues(longer).Should().Be(3);
longer.Take(3).Should().Equal(1, 2, 3);
longer.Skip(3).Should().AllSatisfy(value => value.Should().BeNull());
}
}
Loading