diff --git a/csharp/src/Client/AdbcDataReader.cs b/csharp/src/Client/AdbcDataReader.cs index f0dd1a0ea9..965cb5de52 100644 --- a/csharp/src/Client/AdbcDataReader.cs +++ b/csharp/src/Client/AdbcDataReader.cs @@ -54,7 +54,7 @@ public sealed class AdbcDataReader : DbDataReader, IDbColumnSchemaGenerator private int recordsAffected = -1; /// - /// An event that is raised when a value is read from an Arrow array. + /// An event that is raised when a value is read from an IArrowArray. /// /// /// Callers may opt to provide overrides for parsing values. @@ -86,7 +86,7 @@ internal AdbcDataReader(AdbcCommand adbcCommand, QueryResult adbcQueryResult, De public override object this[int ordinal] => GetValue(ordinal); - public override object this[string name] => GetValue(this.RecordBatch.Column(name), GetOrdinal(name)) ?? DBNull.Value; + public override object this[string name] => GetValue(this.RecordBatch.Column(name)) ?? DBNull.Value; public override int Depth => 0; @@ -247,7 +247,7 @@ public override string GetString(int ordinal) public override object GetValue(int ordinal) { - object? value = GetValue(this.RecordBatch.Column(ordinal), ordinal); + object? value = GetValue(this.RecordBatch.Column(ordinal)); if (value == null) return DBNull.Value; @@ -362,10 +362,10 @@ public ReadOnlyCollection GetAdbcColumnSchema() /// /// /// - public object? GetValue(IArrowArray arrowArray, int ordinal) + private object? GetValue(IArrowArray arrowArray) { // if the OnGetValue event is set, call it - object? result = OnGetValue?.Invoke(arrowArray, ordinal); + object? result = OnGetValue?.Invoke(arrowArray, this.currentRowInRecordBatch); // if the value is null, try to get the value from the ArrowArray result = result ?? arrowArray.ValueAt(this.currentRowInRecordBatch); diff --git a/csharp/test/Apache.Arrow.Adbc.Tests/Client/ClientTests.cs b/csharp/test/Apache.Arrow.Adbc.Tests/Client/ClientTests.cs index 2a919dc7a0..c1d2d59398 100644 --- a/csharp/test/Apache.Arrow.Adbc.Tests/Client/ClientTests.cs +++ b/csharp/test/Apache.Arrow.Adbc.Tests/Client/ClientTests.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Data.SqlTypes; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Apache.Arrow.Adbc.Client; @@ -43,6 +44,56 @@ public void TestDecimalValues(DecimalBehavior decimalBehavior, string value, int Assert.True(rdrValue.GetType().Equals(expectedType)); } + /// + /// Demonstrates the OnGetValue method of an AdbcDataReader. + /// + /// True/False to treat integers as strings. + [Theory] + [InlineData(true)] + [InlineData(false)] + public void TestOnGetValue(bool treatIntegersAsStrings) + { + AdbcDataReader rdr = GetMoqDataReaderForIntegers(); + + if (treatIntegersAsStrings) + { + rdr.OnGetValue += (o, e) => + { + if (o != null) + { + Int32Array? ints = o as Int32Array; + + if (ints != null) + { + int? value = ints.GetValue(e); + + if (value.HasValue) + return value.Value.ToString(); + else + return string.Empty; + } + } + + return string.Empty; + }; + } + + while (rdr.Read()) + { + object? rdrValue = rdr.GetValue(0); + + if (treatIntegersAsStrings) + { + Assert.True(rdrValue.GetType().Equals(typeof(string))); + } + else + { + if (rdrValue != DBNull.Value) + Assert.True(rdrValue.GetType().Equals(typeof(int))); + } + } + } + private AdbcDataReader GetMoqDataReader(DecimalBehavior decimalBehavior, string value, int precision, int scale) { SqlDecimal sqlDecimal = SqlDecimal.Parse(value); @@ -80,6 +131,41 @@ private AdbcDataReader GetMoqDataReader(DecimalBehavior decimalBehavior, string AdbcDataReader reader = cmd.ExecuteReader(); return reader; } + + private AdbcDataReader GetMoqDataReaderForIntegers() + { + List> metadata = new List>(); + List fields = new List(); + fields.Add(new Field("TestIntegers", new Int32Type(), true, metadata)); + + Schema schema = new Schema(fields, metadata); + Int32Array.Builder numbersBuilder = new Int32Array.Builder(); + numbersBuilder.AppendRange(new List() { 1, 2, 3 }); + numbersBuilder.AppendNull(); //null for #4 + numbersBuilder.Append(5); + + Int32Array numbersArray = numbersBuilder.Build(); + + List values = new List() { numbersArray }; + + List records = new List() + { + new RecordBatch(schema, values, numbersArray.Count()) + }; + + MockArrayStream mockArrayStream = new MockArrayStream(schema, records); + QueryResult queryResult = new QueryResult(1, mockArrayStream); + + Mock mockStatement = new Mock(); + mockStatement.Setup(x => x.ExecuteQuery()).Returns(queryResult); ; + + Adbc.Client.AdbcConnection mockConnection = new Adbc.Client.AdbcConnection(); + + AdbcCommand cmd = new AdbcCommand(mockStatement.Object, mockConnection); + + AdbcDataReader reader = cmd.ExecuteReader(); + return reader; + } } class MockArrayStream : IArrowArrayStream