From e7a11cb2e786a313bbf01f53d27d648229e40bf1 Mon Sep 17 00:00:00 2001 From: xqrzd <4950876+xqrzd@users.noreply.github.com> Date: Sat, 12 Feb 2022 12:29:03 -0500 Subject: [PATCH] Improve getting raw/binary values from ResultSet --- src/Knet.Kudu.Client/ResultSet.cs | 39 +++++++++++++------ src/Knet.Kudu.Client/RowResult.cs | 26 ++++++++----- .../KeyEncodingTests.cs | 2 +- .../RowResultTests.cs | 39 +++++++++++-------- 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/src/Knet.Kudu.Client/ResultSet.cs b/src/Knet.Kudu.Client/ResultSet.cs index a388f5ed..bc162fc8 100644 --- a/src/Knet.Kudu.Client/ResultSet.cs +++ b/src/Knet.Kudu.Client/ResultSet.cs @@ -418,23 +418,28 @@ private decimal ReadDecimalUnsafe(ColumnSchema column, int columnIndex, int rowI return KuduEncoder.DecodeDecimalUnsafe(_data!, offset, column.Type, scale); } - internal ReadOnlySpan GetRawFixed(string columnName, int rowIndex) + internal ReadOnlySpan GetSpan(string columnName, int rowIndex) { int columnIndex = GetColumnIndex(columnName); - return GetRawFixed(columnIndex, rowIndex); + return GetSpan(columnIndex, rowIndex); } - internal ReadOnlySpan GetRawFixed(int columnIndex, int rowIndex) + internal ReadOnlySpan GetSpan(int columnIndex, int rowIndex) { - var column = CheckFixedLengthType(columnIndex); + var column = GetColumnSchema(columnIndex); if (IsNullUnsafe(columnIndex, rowIndex)) return default; - int size = column.Size; - int offset = GetStartIndexUnsafe(columnIndex, rowIndex, size); + if (column.IsFixedSize) + { + int size = column.Size; + int offset = GetStartIndexUnsafe(columnIndex, rowIndex, size); + + return _data.AsSpan(offset, size); + } - return _data.AsSpan(offset, size); + return ReadBinaryUnsafe(columnIndex, rowIndex); } internal string GetString(string columnName, int rowIndex) @@ -474,20 +479,32 @@ private string ReadStringUnsafe(int columnIndex, int rowIndex) return KuduEncoder.DecodeString(_data!, offset, length); } - internal ReadOnlySpan GetBinary(string columnName, int rowIndex) + internal byte[] GetBinary(string columnName, int rowIndex) { int columnIndex = GetColumnIndex(columnName); return GetBinary(columnIndex, rowIndex); } - internal ReadOnlySpan GetBinary(int columnIndex, int rowIndex) + internal byte[] GetBinary(int columnIndex, int rowIndex) + { + CheckTypeNotNull(columnIndex, rowIndex, KuduType.Binary); + return ReadBinaryUnsafe(columnIndex, rowIndex).ToArray(); + } + + internal byte[]? GetNullableBinary(string columnName, int rowIndex) + { + int columnIndex = GetColumnIndex(columnName); + return GetNullableBinary(columnIndex, rowIndex); + } + + internal byte[]? GetNullableBinary(int columnIndex, int rowIndex) { CheckType(columnIndex, KuduType.Binary); if (IsNullUnsafe(columnIndex, rowIndex)) - return default; + return null; - return ReadBinaryUnsafe(columnIndex, rowIndex); + return ReadBinaryUnsafe(columnIndex, rowIndex).ToArray(); } private ReadOnlySpan ReadBinaryUnsafe(int columnIndex, int rowIndex) diff --git a/src/Knet.Kudu.Client/RowResult.cs b/src/Knet.Kudu.Client/RowResult.cs index 322331ec..d5151ae8 100644 --- a/src/Knet.Kudu.Client/RowResult.cs +++ b/src/Knet.Kudu.Client/RowResult.cs @@ -145,18 +145,20 @@ public decimal GetDecimal(int columnIndex) => _resultSet.GetNullableDecimal(columnIndex, _index); /// - /// Get the raw value of a fixed length data column. + /// Get the raw value of the given column. /// /// The column name. - public ReadOnlySpan GetRawFixed(string columnName) => - _resultSet.GetRawFixed(columnName, _index); + /// A zero-copy span of the raw value. + public ReadOnlySpan GetSpan(string columnName) => + _resultSet.GetSpan(columnName, _index); /// - /// Get the raw value of a fixed length data column. + /// Get the raw value of the given column. /// /// The column index. - public ReadOnlySpan GetRawFixed(int columnIndex) => - _resultSet.GetRawFixed(columnIndex, _index); + /// A zero-copy span of the raw value. + public ReadOnlySpan GetSpan(int columnIndex) => + _resultSet.GetSpan(columnIndex, _index); public string GetString(string columnName) => _resultSet.GetString(columnName, _index); @@ -170,12 +172,18 @@ public string GetString(int columnIndex) => public string? GetNullableString(int columnIndex) => _resultSet.GetNullableString(columnIndex, _index); - public ReadOnlySpan GetBinary(string columnName) => + public byte[] GetBinary(string columnName) => _resultSet.GetBinary(columnName, _index); - public ReadOnlySpan GetBinary(int columnIndex) => + public byte[] GetBinary(int columnIndex) => _resultSet.GetBinary(columnIndex, _index); + public byte[]? GetNullableBinary(string columnName) => + _resultSet.GetNullableBinary(columnName, _index); + + public byte[]? GetNullableBinary(int columnIndex) => + _resultSet.GetNullableBinary(columnIndex, _index); + public bool IsNull(string columnName) => _resultSet.IsNull(columnName, _index); @@ -232,7 +240,7 @@ public override string ToString() stringBuilder.Append(GetString(i)); break; case KuduType.Binary: - stringBuilder.Append(BitConverter.ToString(GetBinary(i).ToArray())); + stringBuilder.Append(BitConverter.ToString(GetBinary(i))); break; case KuduType.Float: stringBuilder.Append(GetFloat(i)); diff --git a/test/Knet.Kudu.Client.FunctionalTests/KeyEncodingTests.cs b/test/Knet.Kudu.Client.FunctionalTests/KeyEncodingTests.cs index 35a79f63..c6ba5414 100644 --- a/test/Knet.Kudu.Client.FunctionalTests/KeyEncodingTests.cs +++ b/test/Knet.Kudu.Client.FunctionalTests/KeyEncodingTests.cs @@ -83,7 +83,7 @@ public async Task TestAllPrimaryKeyTypes() Assert.Equal(3, row.GetInt32("int32")); Assert.Equal(4, row.GetInt64("int64")); Assert.Equal("foo", row.GetString("string")); - Assert.Equal("bar".ToUtf8ByteArray(), row.GetBinary("binary").ToArray()); + Assert.Equal("bar".ToUtf8ByteArray(), row.GetBinary("binary")); Assert.Equal(6, row.GetInt64("timestamp")); Assert.Equal(DecimalUtil.MaxUnscaledDecimal32, row.GetDecimal("decimal32")); Assert.Equal(DecimalUtil.MaxUnscaledDecimal64, row.GetDecimal("decimal64")); diff --git a/test/Knet.Kudu.Client.FunctionalTests/RowResultTests.cs b/test/Knet.Kudu.Client.FunctionalTests/RowResultTests.cs index 3105f29d..05dde48f 100644 --- a/test/Knet.Kudu.Client.FunctionalTests/RowResultTests.cs +++ b/test/Knet.Kudu.Client.FunctionalTests/RowResultTests.cs @@ -44,7 +44,7 @@ public async Task TestNonNullRows(bool includeNullsInSchema) { Assert.Equal(currentRow, row.GetInt32("key")); Assert.Equal(currentRow, row.GetNullableInt32("key")); - Assert.Equal(KuduEncoder.EncodeInt32(currentRow), row.GetRawFixed("key").ToArray()); + Assert.Equal(KuduEncoder.EncodeInt32(currentRow), row.GetSpan("key").ToArray()); Assert.Equal(42, row.GetByte("int8")); Assert.Equal((byte?)42, row.GetNullableByte("int8")); Assert.Equal(42, row.GetSByte("int8")); @@ -65,7 +65,8 @@ public async Task TestNonNullRows(bool includeNullsInSchema) Assert.Equal("fun with ütf\0", row.GetNullableString("string")); Assert.Equal("árvíztűrő ", row.GetString("varchar")); Assert.Equal("árvíztűrő ", row.GetNullableString("varchar")); - Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, row.GetBinary("binary").ToArray()); + Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, row.GetBinary("binary")); + Assert.Equal(new byte[] { 0, 1, 2, 3, 4 }, row.GetSpan("binary").ToArray()); Assert.Equal(DateTime.Parse("8/19/2020 7:50 PM").ToUniversalTime(), row.GetDateTime("timestamp")); Assert.Equal(DateTime.Parse("8/19/2020 7:50 PM").ToUniversalTime(), row.GetNullableDateTime("timestamp")); Assert.Equal(DateTime.Parse("8/19/2020").ToUniversalTime().Date, row.GetDateTime("date")); @@ -141,25 +142,28 @@ public async Task TestNullRows() Assert.Null(row.GetNullableDouble("double")); Assert.Null(row.GetNullableString("string")); Assert.Null(row.GetNullableString("varchar")); - Assert.Equal(0, row.GetBinary("binary").Length); + Assert.Null(row.GetNullableBinary("binary")); Assert.Null(row.GetNullableDateTime("timestamp")); Assert.Null(row.GetNullableDateTime("date")); Assert.Null(row.GetNullableDecimal("decimal32")); Assert.Null(row.GetNullableDecimal("decimal64")); Assert.Null(row.GetNullableDecimal("decimal128")); - Assert.Equal(0, row.GetRawFixed("int8").Length); - Assert.Equal(0, row.GetRawFixed("int16").Length); - Assert.Equal(0, row.GetRawFixed("int32").Length); - Assert.Equal(0, row.GetRawFixed("int64").Length); - Assert.Equal(0, row.GetRawFixed("bool").Length); - Assert.Equal(0, row.GetRawFixed("float").Length); - Assert.Equal(0, row.GetRawFixed("double").Length); - Assert.Equal(0, row.GetRawFixed("timestamp").Length); - Assert.Equal(0, row.GetRawFixed("date").Length); - Assert.Equal(0, row.GetRawFixed("decimal32").Length); - Assert.Equal(0, row.GetRawFixed("decimal64").Length); - Assert.Equal(0, row.GetRawFixed("decimal128").Length); + Assert.Equal(0, row.GetSpan("int8").Length); + Assert.Equal(0, row.GetSpan("int16").Length); + Assert.Equal(0, row.GetSpan("int32").Length); + Assert.Equal(0, row.GetSpan("int64").Length); + Assert.Equal(0, row.GetSpan("bool").Length); + Assert.Equal(0, row.GetSpan("float").Length); + Assert.Equal(0, row.GetSpan("double").Length); + Assert.Equal(0, row.GetSpan("string").Length); + Assert.Equal(0, row.GetSpan("varchar").Length); + Assert.Equal(0, row.GetSpan("binary").Length); + Assert.Equal(0, row.GetSpan("timestamp").Length); + Assert.Equal(0, row.GetSpan("date").Length); + Assert.Equal(0, row.GetSpan("decimal32").Length); + Assert.Equal(0, row.GetSpan("decimal64").Length); + Assert.Equal(0, row.GetSpan("decimal128").Length); currentRow++; } } @@ -239,7 +243,7 @@ public async Task TestResultSetDispose() Assert.Throws(() => row.GetInt32("key")); Assert.Throws(() => row.GetNullableInt32("key")); - Assert.Throws(() => row.GetRawFixed("key")); + Assert.Throws(() => row.GetSpan("key")); Assert.Throws(() => row.GetByte("int8")); Assert.Throws(() => row.GetNullableByte("int8")); Assert.Throws(() => row.GetSByte("int8")); @@ -260,7 +264,8 @@ public async Task TestResultSetDispose() Assert.Throws(() => row.GetNullableString("string")); Assert.Throws(() => row.GetString("varchar")); Assert.Throws(() => row.GetNullableString("varchar")); - Assert.Throws(() => row.GetBinary("binary").ToArray()); + Assert.Throws(() => row.GetBinary("binary")); + Assert.Throws(() => row.GetNullableBinary("binary")); Assert.Throws(() => row.GetDateTime("timestamp")); Assert.Throws(() => row.GetNullableDateTime("timestamp")); Assert.Throws(() => row.GetDateTime("date"));