This is an automated email from the ASF dual-hosted git repository.
CurtHagenlocher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-dotnet.git
The following commit(s) were added to refs/heads/main by this push:
new 3ea9aaa Unambiguously equate decimal16 with SqlDecimal in Variant API
(#342)
3ea9aaa is described below
commit 3ea9aaae80c2a8a406d0726a01950e4f31032b98
Author: Curt Hagenlocher <[email protected]>
AuthorDate: Wed Apr 29 17:11:42 2026 -0700
Unambiguously equate decimal16 with SqlDecimal in Variant API (#342)
## What's Changed
Unambiguously equate `decimal16` with `SqlDecimal` in Variant API
Closes #333.
---
.../Shredding/VariantShredder.cs | 4 +-
.../VariantJson/VariantJsonConverter.cs | 6 +-
src/Apache.Arrow.Scalars/Variant/VariantValue.cs | 125 ++++++++++-----------
.../Variant/VariantValueWriter.cs | 16 ++-
.../Shredding/ShreddedVariantReaderTests.cs | 2 +-
.../ParquetTestingVectorTests.cs | 2 +-
.../VariantSqlDecimalTests.cs | 60 +++++-----
.../VariantValueTests.cs | 30 ++---
8 files changed, 116 insertions(+), 129 deletions(-)
diff --git a/src/Apache.Arrow.Operations/Shredding/VariantShredder.cs
b/src/Apache.Arrow.Operations/Shredding/VariantShredder.cs
index 0a825b3..ef2ed11 100644
--- a/src/Apache.Arrow.Operations/Shredding/VariantShredder.cs
+++ b/src/Apache.Arrow.Operations/Shredding/VariantShredder.cs
@@ -283,8 +283,8 @@ namespace Apache.Arrow.Operations.Shredding
case ShredType.Float: return value.AsFloat();
case ShredType.Double: return value.AsDouble();
case ShredType.Decimal4:
- case ShredType.Decimal8:
- case ShredType.Decimal16: return value.AsDecimal();
+ case ShredType.Decimal8: return value.AsDecimal();
+ case ShredType.Decimal16: return value.AsSqlDecimal();
case ShredType.Date: return value.AsDateDays();
case ShredType.Timestamp: return value.AsTimestampMicros();
case ShredType.TimestampNtz: return
value.AsTimestampNtzMicros();
diff --git a/src/Apache.Arrow.Operations/VariantJson/VariantJsonConverter.cs
b/src/Apache.Arrow.Operations/VariantJson/VariantJsonConverter.cs
index 843cd69..de11c97 100644
--- a/src/Apache.Arrow.Operations/VariantJson/VariantJsonConverter.cs
+++ b/src/Apache.Arrow.Operations/VariantJson/VariantJsonConverter.cs
@@ -243,10 +243,8 @@ namespace Apache.Arrow.Operations.VariantJson
writer.WriteNumberValue(value.AsDecimal());
break;
case VariantPrimitiveType.Decimal16:
- if (value.IsSqlDecimalStorage)
- writer.WriteRawValue(value.AsSqlDecimal().ToString());
- else
- writer.WriteNumberValue(value.AsDecimal());
+ // SqlDecimal.ToString() is culture-agnostic and produces
a plain decimal string without exponent
+ writer.WriteRawValue(value.AsSqlDecimal().ToString());
break;
case VariantPrimitiveType.Date:
DateTime date = value.AsDate();
diff --git a/src/Apache.Arrow.Scalars/Variant/VariantValue.cs
b/src/Apache.Arrow.Scalars/Variant/VariantValue.cs
index 8848ca7..005a4e9 100644
--- a/src/Apache.Arrow.Scalars/Variant/VariantValue.cs
+++ b/src/Apache.Arrow.Scalars/Variant/VariantValue.cs
@@ -19,6 +19,9 @@ using System.Data.SqlTypes;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
+#if !NET8_0_OR_GREATER
+using System.Runtime.InteropServices;
+#endif
namespace Apache.Arrow.Scalars.Variant
{
@@ -109,27 +112,15 @@ namespace Apache.Arrow.Scalars.Variant
public static VariantValue FromDecimal8(decimal value) =>
new VariantValue(VariantPrimitiveType.Decimal8, (object)value);
- /// <summary>Creates a Decimal16 variant value.</summary>
- public static VariantValue FromDecimal16(decimal value) =>
- new VariantValue(VariantPrimitiveType.Decimal16, (object)value);
-
/// <summary>
- /// Creates a Decimal16 variant value from a <see cref="SqlDecimal"/>,
always
- /// producing <see cref="VariantPrimitiveType.Decimal16"/>. Values
exceeding
- /// <see cref="decimal"/> range are stored as <see cref="SqlDecimal"/>.
- /// Use this when the target type is known (e.g. materializing a
Decimal16
- /// shredded column); use <see cref="FromSqlDecimal(SqlDecimal)"/>
when you
- /// want the smallest decimal type that fits the value.
+ /// Creates a Decimal16 variant value. Decimal16 covers the full
Parquet
+ /// 38-digit decimal range, which exceeds the <see cref="decimal"/>
96-bit
+ /// mantissa, so the API uses <see cref="SqlDecimal"/> uniformly. Use
+ /// <see cref="FromSqlDecimal(SqlDecimal)"/> when you want the smallest
+ /// decimal type that fits the value.
/// </summary>
- public static VariantValue FromDecimal16(SqlDecimal value)
- {
- if (value.Data[3] != 0)
- {
- SqlDecimal normalized = SqlDecimal.ConvertToPrecScale(value,
38, value.Scale);
- return new VariantValue(VariantPrimitiveType.Decimal16,
(object)normalized);
- }
- return new VariantValue(VariantPrimitiveType.Decimal16,
(object)value.Value);
- }
+ public static VariantValue FromDecimal16(SqlDecimal value) =>
+ new VariantValue(VariantPrimitiveType.Decimal16, (object)value);
/// <summary>
/// Creates a decimal variant value, choosing the smallest decimal type
@@ -152,37 +143,47 @@ namespace Apache.Arrow.Scalars.Variant
{
return FromDecimal8(value);
}
- return FromDecimal16(value);
+ return new VariantValue(VariantPrimitiveType.Decimal16,
(object)new SqlDecimal(value));
}
/// <summary>
- /// Creates a decimal variant value from a <see cref="SqlDecimal"/>.
- /// Values fitting in <see cref="decimal"/> are stored as
Decimal4/8/16 using
- /// the smallest type. Values exceeding <see cref="decimal"/> range
are stored
- /// as Decimal16 with <see cref="SqlDecimal"/> storage.
+ /// Creates a decimal variant value from a <see cref="SqlDecimal"/>,
choosing
+ /// the smallest decimal type that fits. Values exceeding <see
cref="decimal"/>
+ /// range produce a Decimal16.
/// </summary>
public static VariantValue FromSqlDecimal(SqlDecimal value)
{
- int[] data = value.Data;
+#if NET8_0_OR_GREATER
+ Span<uint> data = stackalloc uint[4];
+ value.WriteTdsValue(data);
+#else
+ ReadOnlySpan<uint> data = MemoryMarshal.Cast<int,
uint>(value.Data);
+#endif
+
// SqlDecimal.Data: [0]=least-significant, [3]=most-significant
- if (data[3] != 0)
+ if (data[3] == 0 && value.Precision - value.Scale <= 28)
{
- // Exceeds 96 bits — must store as SqlDecimal
- SqlDecimal normalized = SqlDecimal.ConvertToPrecScale(value,
38, value.Scale);
- return new VariantValue(VariantPrimitiveType.Decimal16,
(object)normalized);
+ try
+ {
+ // Fits in decimal — convert and dispatch
+ decimal d = value.Value;
+ if (data[2] == 0 && data[1] == 0)
+ {
+ return FromDecimal4(d);
+ }
+ if (data[2] == 0)
+ {
+ return FromDecimal8(d);
+ }
+ }
+ catch (OverflowException)
+ {
+ // Value exceeds decimal range — fall back to Decimal16
+ }
}
- // Fits in decimal — convert and dispatch
- decimal d = value.Value;
- if (data[2] == 0 && data[1] == 0)
- {
- return FromDecimal4(d);
- }
- if (data[2] == 0)
- {
- return FromDecimal8(d);
- }
- return FromDecimal16(d);
+ // Exceeds 96 bits — must store as SqlDecimal
+ return new VariantValue(VariantPrimitiveType.Decimal16,
(object)value);
}
/// <summary>Creates a Date variant value from days since
epoch.</summary>
@@ -355,51 +356,45 @@ namespace Apache.Arrow.Scalars.Variant
return BitConverter.Int64BitsToDouble(_inlineValue);
}
- /// <summary>Gets a decimal value (works for Decimal4, Decimal8, and
Decimal16).</summary>
- /// <remarks>
- /// For Decimal16 values stored as <see cref="SqlDecimal"/> (exceeding
96 bits),
- /// this will throw <see cref="OverflowException"/>. Use <see
cref="AsSqlDecimal()"/> instead.
- /// </remarks>
+ /// <summary>
+ /// Gets a decimal value. Supported for Decimal4 and Decimal8 only.
+ /// Decimal16 can hold 38-digit values that exceed <see
cref="decimal"/>
+ /// range, so use <see cref="AsSqlDecimal()"/> for Decimal16 instead.
+ /// </summary>
public decimal AsDecimal()
{
if (_primitiveType == VariantPrimitiveType.Decimal4 ||
- _primitiveType == VariantPrimitiveType.Decimal8 ||
- _primitiveType == VariantPrimitiveType.Decimal16)
+ _primitiveType == VariantPrimitiveType.Decimal8)
{
- if (_objectValue is SqlDecimal sd)
- return sd.Value;
return (decimal)_objectValue;
}
+ if (_primitiveType == VariantPrimitiveType.Decimal16)
+ {
+ throw new InvalidOperationException(
+ "Cannot read Decimal16 as System.Decimal; use
AsSqlDecimal() instead.");
+ }
throw new InvalidOperationException($"Cannot read decimal from
variant type {_primitiveType}.");
}
/// <summary>
- /// Gets a decimal value as a <see cref="SqlDecimal"/> (works for
Decimal4, Decimal8, and Decimal16).
- /// Unlike <see cref="AsDecimal()"/>, this method does not throw for
large Decimal16 values.
+ /// Gets a decimal value as a <see cref="SqlDecimal"/>. Works for
Decimal4,
+ /// Decimal8, and Decimal16 (including values that exceed <see
cref="decimal"/>
+ /// range).
/// </summary>
public SqlDecimal AsSqlDecimal()
{
if (_primitiveType == VariantPrimitiveType.Decimal4 ||
- _primitiveType == VariantPrimitiveType.Decimal8 ||
- _primitiveType == VariantPrimitiveType.Decimal16)
+ _primitiveType == VariantPrimitiveType.Decimal8)
{
- if (_objectValue is SqlDecimal sd)
- return sd;
return new SqlDecimal((decimal)_objectValue);
}
+ if (_primitiveType == VariantPrimitiveType.Decimal16)
+ {
+ return (SqlDecimal)_objectValue;
+ }
throw new InvalidOperationException($"Cannot read decimal from
variant type {_primitiveType}.");
}
- /// <summary>
- /// Returns true when the decimal value is stored internally as <see
cref="SqlDecimal"/>
- /// (i.e., it exceeds the range of <see cref="decimal"/>).
- /// </summary>
- internal bool IsSqlDecimalStorage =>
- (_primitiveType == VariantPrimitiveType.Decimal4 ||
- _primitiveType == VariantPrimitiveType.Decimal8 ||
- _primitiveType == VariantPrimitiveType.Decimal16) &&
- _objectValue is SqlDecimal;
-
/// <summary>Gets the Date value as days since epoch.</summary>
public int AsDateDays()
{
diff --git a/src/Apache.Arrow.Scalars/Variant/VariantValueWriter.cs
b/src/Apache.Arrow.Scalars/Variant/VariantValueWriter.cs
index 781f4a4..7adc36b 100644
--- a/src/Apache.Arrow.Scalars/Variant/VariantValueWriter.cs
+++ b/src/Apache.Arrow.Scalars/Variant/VariantValueWriter.cs
@@ -17,6 +17,9 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.Data.SqlTypes;
+#if !NET8_0_OR_GREATER
+using System.Runtime.InteropServices;
+#endif
using System.Text;
namespace Apache.Arrow.Scalars.Variant
@@ -397,12 +400,17 @@ namespace Apache.Arrow.Scalars.Variant
buf.Append(VariantEncodingHelper.MakePrimitiveHeader(VariantPrimitiveType.Decimal16));
bool positive = value.IsPositive;
- byte scale = (byte)value.Scale;
- int[] data = value.Data;
+ byte scale = value.Scale;
+#if NET8_0_OR_GREATER
+ Span<uint> data = stackalloc uint[4];
+ value.WriteTdsValue(data);
+#else
+ ReadOnlySpan<uint> data = MemoryMarshal.Cast<int,
uint>(value.Data);
+#endif
// SqlDecimal.Data: [0]=least-significant, [3]=most-significant
- long lo = ((long)(uint)data[1] << 32) | (uint)data[0];
- long hi = ((long)(uint)data[3] << 32) | (uint)data[2];
+ long lo = ((long)data[1] << 32) | data[0];
+ long hi = ((long)data[3] << 32) | data[2];
if (!positive)
{
diff --git
a/test/Apache.Arrow.Operations.Tests/Shredding/ShreddedVariantReaderTests.cs
b/test/Apache.Arrow.Operations.Tests/Shredding/ShreddedVariantReaderTests.cs
index 1cf52f6..3b1fcf4 100644
--- a/test/Apache.Arrow.Operations.Tests/Shredding/ShreddedVariantReaderTests.cs
+++ b/test/Apache.Arrow.Operations.Tests/Shredding/ShreddedVariantReaderTests.cs
@@ -481,7 +481,7 @@ namespace Apache.Arrow.Operations.Tests.Shredding
// is retained with SqlDecimal storage inside the VariantValue.
VariantValue v = array.GetLogicalVariantValue(0);
Assert.Equal(expected, v.AsSqlDecimal());
- Assert.Throws<OverflowException>(() => v.AsDecimal());
+ Assert.Throws<InvalidOperationException>(() => v.AsDecimal());
}
/// <summary>
diff --git a/test/Apache.Arrow.Scalars.Tests/ParquetTestingVectorTests.cs
b/test/Apache.Arrow.Scalars.Tests/ParquetTestingVectorTests.cs
index a3c6ee3..b2b3529 100644
--- a/test/Apache.Arrow.Scalars.Tests/ParquetTestingVectorTests.cs
+++ b/test/Apache.Arrow.Scalars.Tests/ParquetTestingVectorTests.cs
@@ -331,7 +331,7 @@ namespace Apache.Arrow.Scalars.Tests
// JSON may lose precision for large decimals (e.g.
1.2345678912345678e+16
// loses the fractional part). Use relative tolerance
comparison.
double expectedD16 = expected.GetDouble();
- double actualD16 = (double)actual.AsDecimal();
+ double actualD16 = actual.AsSqlDecimal().ToDouble();
double relError = Math.Abs(expectedD16 - actualD16) /
Math.Max(1.0, Math.Abs(expectedD16));
Assert.True(relError < 1e-10,
$"{context}: decimal16 relative error {relError:E3}
exceeds tolerance. " +
diff --git a/test/Apache.Arrow.Scalars.Tests/VariantSqlDecimalTests.cs
b/test/Apache.Arrow.Scalars.Tests/VariantSqlDecimalTests.cs
index a0be0e9..f2e539f 100644
--- a/test/Apache.Arrow.Scalars.Tests/VariantSqlDecimalTests.cs
+++ b/test/Apache.Arrow.Scalars.Tests/VariantSqlDecimalTests.cs
@@ -167,13 +167,30 @@ namespace Apache.Arrow.Scalars.Tests
// FromSqlDecimal — large values produce Decimal16
// ---------------------------------------------------------------
+ [Fact]
+ public void Decimal16_FromDecimalAndFromSqlDecimal_SameValue_AreEqual()
+ {
+ // A value requiring all 96 bits — auto-sizes to Decimal16 via
FromDecimal,
+ // and constructs the same Decimal16 via
FromDecimal16(SqlDecimal). The two
+ // must be equal and have the same hash code regardless of how
_objectValue
+ // is boxed internally.
+ decimal d = 79228162514264337593543950335m;
+ VariantValue fromDecimal = VariantValue.FromDecimal(d);
+ VariantValue fromSqlDecimal = VariantValue.FromDecimal16(new
SqlDecimal(d));
+
+ Assert.Equal(VariantPrimitiveType.Decimal16,
fromDecimal.PrimitiveType);
+ Assert.Equal(VariantPrimitiveType.Decimal16,
fromSqlDecimal.PrimitiveType);
+ Assert.Equal(fromDecimal, fromSqlDecimal);
+ Assert.Equal(fromDecimal.GetHashCode(),
fromSqlDecimal.GetHashCode());
+ }
+
[Fact]
public void FromSqlDecimal_LargeValue_ProducesDecimal16()
{
SqlDecimal sd =
SqlDecimal.Parse("99999999999999999999999999999999999999");
VariantValue vv = VariantValue.FromSqlDecimal(sd);
Assert.Equal(VariantPrimitiveType.Decimal16, vv.PrimitiveType);
- Assert.True(vv.IsSqlDecimalStorage);
+ Assert.Equal(sd, vv.AsSqlDecimal());
}
// ---------------------------------------------------------------
@@ -198,15 +215,15 @@ namespace Apache.Arrow.Scalars.Tests
}
// ---------------------------------------------------------------
- // AsDecimal from SqlDecimal-stored Decimal16 throws OverflowException
+ // AsDecimal on Decimal16 always throws (regardless of internal
storage)
// ---------------------------------------------------------------
[Fact]
- public void AsDecimal_FromSqlDecimalStored_Throws()
+ public void AsDecimal_OnLargeDecimal16_Throws()
{
SqlDecimal sd =
SqlDecimal.Parse("99999999999999999999999999999999999999");
VariantValue vv = VariantValue.FromSqlDecimal(sd);
- Assert.Throws<OverflowException>(() => vv.AsDecimal());
+ Assert.Throws<InvalidOperationException>(() => vv.AsDecimal());
}
// ---------------------------------------------------------------
@@ -271,7 +288,6 @@ namespace Apache.Arrow.Scalars.Tests
// Should not throw — should use SqlDecimal path
VariantValue vv = reader.ToVariantValue();
Assert.Equal(VariantPrimitiveType.Decimal16, vv.PrimitiveType);
- Assert.True(vv.IsSqlDecimalStorage);
SqlDecimal result = vv.AsSqlDecimal();
Assert.Equal(SqlDecimal.Parse("79228162514264337593543950336"),
result);
@@ -293,15 +309,14 @@ namespace Apache.Arrow.Scalars.Tests
VariantValue vv2 = reader.ToVariantValue();
Assert.Equal(VariantPrimitiveType.Decimal16, vv2.PrimitiveType);
- Assert.True(vv2.IsSqlDecimalStorage);
Assert.Equal(original, vv2.AsSqlDecimal());
}
[Fact]
- public void RoundTrip_Materialize_SmallDecimal16_UsesDecimalStorage()
+ public void RoundTrip_Materialize_SmallDecimal16()
{
- decimal d = 12345.67m;
- VariantValue vv1 = VariantValue.FromDecimal16(d);
+ SqlDecimal sd = new SqlDecimal(12345.67m);
+ VariantValue vv1 = VariantValue.FromDecimal16(sd);
VariantBuilder builder = new VariantBuilder();
(byte[] metadata, byte[] value) = builder.Encode(vv1);
@@ -309,8 +324,7 @@ namespace Apache.Arrow.Scalars.Tests
VariantValue vv2 = reader.ToVariantValue();
Assert.Equal(VariantPrimitiveType.Decimal16, vv2.PrimitiveType);
- Assert.False(vv2.IsSqlDecimalStorage);
- Assert.Equal(d, vv2.AsDecimal());
+ Assert.Equal(sd, vv2.AsSqlDecimal());
}
// ---------------------------------------------------------------
@@ -434,7 +448,6 @@ namespace Apache.Arrow.Scalars.Tests
SqlDecimal sd = new SqlDecimal(0m);
VariantValue vv = VariantValue.FromSqlDecimal(sd);
Assert.Equal(VariantPrimitiveType.Decimal4, vv.PrimitiveType);
- Assert.False(vv.IsSqlDecimalStorage);
Assert.Equal(0m, vv.AsDecimal());
}
@@ -443,27 +456,13 @@ namespace Apache.Arrow.Scalars.Tests
// ---------------------------------------------------------------
[Fact]
- public void
FromSqlDecimal_96BitBoundary_ProducesDecimal16WithDecimalStorage()
+ public void FromSqlDecimal_96BitBoundary_ProducesDecimal16()
{
// A value that needs all 96 bits: data[2] != 0 but data[3] == 0
SqlDecimal sd = new SqlDecimal(79228162514264337593543950335m);
VariantValue vv = VariantValue.FromSqlDecimal(sd);
Assert.Equal(VariantPrimitiveType.Decimal16, vv.PrimitiveType);
- Assert.False(vv.IsSqlDecimalStorage); // stored as decimal, not
SqlDecimal
- Assert.Equal(79228162514264337593543950335m, vv.AsDecimal());
- }
-
- // ---------------------------------------------------------------
- // AsDecimal on Decimal16 that was created via FromSqlDecimal but fits
- // ---------------------------------------------------------------
-
- [Fact]
- public void AsDecimal_FromSqlDecimalThatFits()
- {
- // 96-bit value goes through FromSqlDecimal -> stored as decimal
- SqlDecimal sd = new SqlDecimal(79228162514264337593543950335m);
- VariantValue vv = VariantValue.FromSqlDecimal(sd);
- Assert.Equal(79228162514264337593543950335m, vv.AsDecimal());
+ Assert.Equal(sd, vv.AsSqlDecimal());
}
// ---------------------------------------------------------------
@@ -512,7 +511,6 @@ namespace Apache.Arrow.Scalars.Tests
Assert.True(materialized.IsObject);
IReadOnlyDictionary<string, VariantValue> fields =
materialized.AsObject();
Assert.Equal(sd, fields["big"].AsSqlDecimal());
- Assert.True(fields["big"].IsSqlDecimalStorage);
Assert.Equal(42.5m, fields["small"].AsDecimal());
}
@@ -534,10 +532,8 @@ namespace Apache.Arrow.Scalars.Tests
Assert.True(materialized.IsArray);
IReadOnlyList<VariantValue> elements = materialized.AsArray();
Assert.Equal(3, elements.Count);
- Assert.True(elements[0].IsSqlDecimalStorage);
Assert.Equal(large, elements[0].AsSqlDecimal());
- Assert.False(elements[1].IsSqlDecimalStorage);
- Assert.Equal(42.5m, elements[1].AsDecimal());
+ Assert.Equal(new SqlDecimal(42.5m), elements[1].AsSqlDecimal());
Assert.Equal(1.23m, elements[2].AsDecimal());
}
diff --git a/test/Apache.Arrow.Scalars.Tests/VariantValueTests.cs
b/test/Apache.Arrow.Scalars.Tests/VariantValueTests.cs
index e5187dc..6c4d829 100644
--- a/test/Apache.Arrow.Scalars.Tests/VariantValueTests.cs
+++ b/test/Apache.Arrow.Scalars.Tests/VariantValueTests.cs
@@ -152,10 +152,17 @@ namespace Apache.Arrow.Scalars.Tests
[Fact]
public void Decimal16()
{
- decimal d = 79228162514264337593543950335m;
- VariantValue v = VariantValue.FromDecimal16(d);
+ SqlDecimal sd = new SqlDecimal(79228162514264337593543950335m);
+ VariantValue v = VariantValue.FromDecimal16(sd);
Assert.Equal(VariantPrimitiveType.Decimal16, v.PrimitiveType);
- Assert.Equal(d, v.AsDecimal());
+ Assert.Equal(sd, v.AsSqlDecimal());
+ }
+
+ [Fact]
+ public void AsDecimal_OnDecimal16_Throws()
+ {
+ VariantValue v = VariantValue.FromDecimal16(new SqlDecimal(42.5m));
+ Assert.Throws<InvalidOperationException>(() => v.AsDecimal());
}
[Fact]
@@ -458,23 +465,6 @@ namespace Apache.Arrow.Scalars.Tests
Assert.Equal(fromDecimal4.GetHashCode(),
fromSqlDecimal.GetHashCode());
}
- [Fact]
- public void IsSqlDecimalStorage_FalseForNonDecimalTypes()
- {
- Assert.False(VariantValue.FromInt32(42).IsSqlDecimalStorage);
- Assert.False(VariantValue.FromString("hello").IsSqlDecimalStorage);
- Assert.False(VariantValue.Null.IsSqlDecimalStorage);
- Assert.False(VariantValue.FromDouble(3.14).IsSqlDecimalStorage);
- }
-
- [Fact]
- public void IsSqlDecimalStorage_FalseForDecimalStoredValues()
- {
- Assert.False(VariantValue.FromDecimal4(42.5m).IsSqlDecimalStorage);
-
Assert.False(VariantValue.FromDecimal8(123456789.12m).IsSqlDecimalStorage);
-
Assert.False(VariantValue.FromDecimal16(42.5m).IsSqlDecimalStorage);
- }
-
// ---------------------------------------------------------------
// ToString with SqlDecimal storage
// ---------------------------------------------------------------