diff options
author | Damien Diederen <dd@crosstwine.com> | 2015-01-16 17:05:51 +0300 |
---|---|---|
committer | Damien Diederen <dd@crosstwine.com> | 2015-05-05 22:20:49 +0300 |
commit | 3a81bfc27525bcec2fa04340fcd1567347c04ca9 (patch) | |
tree | aba5c3b4075a445dcdca85263d60811cb2cddd40 /mcs/class/Mono.Data.Tds | |
parent | 77ef86e529eea9e20ae3219c9738e29a440f275b (diff) |
[Mono.Data.Tds] Deserialize variant-wrapped fixed-size integers (1-8 bytes)
Without this, variant output parameters are left unconsumed in the
input stream, and null is returned.
The new code skips the max length uint, and decodes a subset of the
variant types. What is not recognized is skipped, and we return null
as the previous code used to do.
(Ideally, the subset of GetColumnValue which decodes types which can
be embedded in a variant should be factored out to a different method,
and reused from GetVariantValue.)
Diffstat (limited to 'mcs/class/Mono.Data.Tds')
-rw-r--r-- | mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs index 0cee960df52..5cb0ae8a4ce 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs @@ -932,6 +932,11 @@ namespace Mono.Data.Tds.Protocol element = new Guid (guidBytes); } break; + case TdsColumnType.Variant : + if (outParam) + comm.Skip (4); + element = GetVariantValue(); + break; default : return DBNull.Value; } @@ -956,6 +961,40 @@ namespace Mono.Data.Tds.Protocol return result; } + private object GetVariantValue () + { + uint len = (uint)comm.GetTdsInt (); + if (len == 0) + return DBNull.Value; + + // VARIANT_BASETYPE + TdsColumnType colType = (TdsColumnType)comm.GetByte (); + // VARIANT_PROPBYTES + byte propbytes = comm.GetByte (); + if (propbytes != 0) + // VARIANT_PROPERTIES + comm.Skip (propbytes); + + len -= (uint)propbytes + 2; + + switch (colType) + { + case TdsColumnType.Int1 : + case TdsColumnType.Int2 : + case TdsColumnType.Int4 : + case TdsColumnType.BigInt : + return GetIntValue (colType); + default: + // The old code was ignoring variants + // and returning null. Should we + // throw an exception? + comm.Skip (len); + break; + } + + return DBNull.Value; + } + private object GetDateTimeValue ( TdsColumnType? type ) |