Beispiel #1
0
        internal SqlDataRecord(SmiRecordBuffer recordBuffer, params SmiExtendedMetaData[] metaData)
        {
            Debug.Assert(null != recordBuffer, "invalid attempt to instantiate SqlDataRecord with null SmiRecordBuffer");
            Debug.Assert(null != metaData, "invalid attempt to instantiate SqlDataRecord with null SmiExtendedMetaData[]");

            _columnMetaData    = new SqlMetaData[metaData.Length];
            _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
            for (int i = 0; i < _columnSmiMetaData.Length; i++)
            {
                _columnSmiMetaData[i] = metaData[i];
                _columnMetaData[i]    = MetaDataUtilsSmi.SmiExtendedMetaDataToSqlMetaData(_columnSmiMetaData[i]);
            }

            _eventSink = new SmiEventSink_Default();

            if (InOutOfProcHelper.InProc)
            {
                _recordContext = SmiContextFactory.Instance.GetCurrentContext();
            }
            else
            {
                _recordContext = null;
            }
            _recordBuffer = recordBuffer;
            _eventSink.ProcessMessagesAndThrow();
        }
Beispiel #2
0
 internal SqlClientWrapperSmiStream(SmiEventSink_Default sink, SmiStream stream)
 {
     Debug.Assert(null != sink);
     Debug.Assert(null != stream);
     _sink   = sink;
     _stream = stream;
 }
Beispiel #3
0
        protected virtual void DispatchMessages(
#if NETFRAMEWORK
            bool ignoreNonFatalMessages
#endif
            )
        {
            // virtual because we want a default implementation in the cases
            // where we don't have a connection to process stuff, but we want to
            // provide the connection the ability to fire info messages when it
            // hooks up.
#if NETFRAMEWORK
            SmiEventSink_Default parent = (SmiEventSink_Default)_parent;
            if (null != parent)
            {
                parent.DispatchMessages(ignoreNonFatalMessages);
            }
            else
#endif
            {
                SqlException errors = ProcessMessages(true
#if NETFRAMEWORK
                                                      , ignoreNonFatalMessages
#endif
                                                      ); // ignore warnings, because there's no place to send them...
                if (null != errors)
                {
                    throw errors;
                }
            }
        }
Beispiel #4
0
        //  SqlDataRecord public API
        /// <include file='../../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/ctor/*' />
        public SqlDataRecord(params SqlMetaData[] metaData)
        {
            // Initial consistency check
            if (null == metaData)
            {
                throw ADP.ArgumentNull(nameof(metaData));
            }

            _columnMetaData    = new SqlMetaData[metaData.Length];
            _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
            for (int i = 0; i < _columnSmiMetaData.Length; i++)
            {
                if (null == metaData[i])
                {
                    throw ADP.ArgumentNull($"{nameof(metaData)}[{i}]");
                }
                _columnMetaData[i]    = metaData[i];
                _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(_columnMetaData[i]);
            }

            _eventSink = new SmiEventSink_Default();

            _recordBuffer            = new MemoryRecordBuffer(_columnSmiMetaData);
            _usesStringStorageForXml = true;
            _eventSink.ProcessMessagesAndThrow();
        }
        internal static TextReader GetTextReader(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData)
        {
            bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal);

            // If a sql_variant, get the internal type
            if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant))
            {
                metaData = getters.GetVariantType(sink, ordinal);
            }
            // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast
            if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TextReader)))
            {
                throw ADP.InvalidCast();
            }

            string data;

            if (isDbNull)
            {
                // "null" textreader
                data = string.Empty;
            }
            else
            {
                // Read all data
                data = GetString_Unchecked(sink, getters, ordinal);
            }

            // Wrap in pre-built object
            return(new StringReader(data));
        }
        internal static Stream GetStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool bypassTypeCheck = false)
        {
            bool isDbNull = ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal);

            // If a sql_variant, get the internal type
            if (!bypassTypeCheck)
            {
                if ((!isDbNull) && (metaData.SqlDbType == SqlDbType.Variant))
                {
                    metaData = getters.GetVariantType(sink, ordinal);
                }
                // If the SqlDbType is still variant, then it must contain null, so don't throw InvalidCast
                if ((metaData.SqlDbType != SqlDbType.Variant) && (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.Stream)))
                {
                    throw ADP.InvalidCast();
                }
            }

            byte[] data;
            if (isDbNull)
            {
                // "null" stream
                data = new byte[0];
            }
            else
            {
                // Read all data
                data = GetByteArray_Unchecked(sink, getters, ordinal);
            }

            // Wrap data in pre-built object
            return(new MemoryStream(data, writable: false));
        }
Beispiel #7
0
        private SmiContextFactory()
        {
            if (InOutOfProcHelper.InProc)
            {
                Type smiLinkType = Type.GetType("Microsoft.SqlServer.Server.InProcLink, SqlAccess, PublicKeyToken=89845dcd8080cc91");

                if (null == smiLinkType)
                {
                    Debug.Assert(false, "could not get InProcLink type");
                    throw SQL.ContextUnavailableOutOfProc();    // Must not be a valid version of Sql Server.
                }

                System.Reflection.FieldInfo instanceField = GetStaticField(smiLinkType, "Instance");
                if (instanceField != null)
                {
                    _smiLink = (SmiLink)GetValue(instanceField);
                }
                else
                {
                    Debug.Assert(false, "could not get InProcLink.Instance");
                    throw SQL.ContextUnavailableOutOfProc();    // Must not be a valid version of Sql Server.
                }

                System.Reflection.FieldInfo buildVersionField = GetStaticField(smiLinkType, "BuildVersion");
                if (buildVersionField != null)
                {
                    UInt32 buildVersion = (UInt32)GetValue(buildVersionField);

                    _majorVersion  = (byte)(buildVersion >> 24);
                    _minorVersion  = (byte)((buildVersion >> 16) & 0xff);
                    _buildNum      = (short)(buildVersion & 0xffff);
                    _serverVersion = (String.Format((IFormatProvider)null, "{0:00}.{1:00}.{2:0000}", _majorVersion, (short)_minorVersion, _buildNum));
                }
                else
                {
                    _serverVersion = String.Empty;  // default value if nothing exists.
                }
                _negotiatedSmiVersion = _smiLink.NegotiateVersion(SmiLink.InterfaceVersion);
                bool isSupportedVersion = false;
                for (int i = 0; !isSupportedVersion && i < __supportedSmiVersions.Length; i++)
                {
                    if (__supportedSmiVersions[i] == _negotiatedSmiVersion)
                    {
                        isSupportedVersion = true;
                    }
                }

                // Disconnect if we didn't get a supported version!!
                if (!isSupportedVersion)
                {
                    _smiLink = null;
                }

                _eventSinkForGetCurrentContext = new SmiEventSink_Default();
            }
        }
        // UDTs and null variants come back via return value, all else is via targetBuffer.
        //  implements SqlClient 1.1-compatible output parameter semantics
        internal static object GetOutputParameterV200Smi(
            SmiEventSink_Default sink,    // event sink for errors
            SmiTypedGetterSetter getters, // getters interface to grab value from
            int ordinal,                  // parameter within getters
            SmiMetaData metaData,         // Getter's type for this ordinal
            SmiContext context,           // used to obtain scratch streams
            SqlBuffer targetBuffer        // destination
            )
        {
            object result = null;   // Workaround for UDT hack in non-Smi code paths.

            if (IsDBNull_Unchecked(sink, getters, ordinal))
            {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
            }
            else
            {
                switch (metaData.SqlDbType)
                {
                // new types go here
                case SqlDbType.Variant:     // Handle variants specifically for v200, since they could contain v200 types
                    // For variants, recur using the current value's sqldbtype
                    metaData = getters.GetVariantType(sink, ordinal);
                    sink.ProcessMessagesAndThrow();
                    Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!");
                    GetOutputParameterV200Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    break;

                case SqlDbType.Date:
                    targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal));
                    break;

                case SqlDbType.DateTime2:
                    targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                case SqlDbType.Time:
                    targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                case SqlDbType.DateTimeOffset:
                    targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale);
                    break;

                default:
                    result = GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    break;
                }
            }

            return(result);
        }
Beispiel #9
0
        internal SmiGettersStream(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData)
        {
            Debug.Assert(null != sink);
            Debug.Assert(null != getters);
            Debug.Assert(0 <= ordinal);
            Debug.Assert(null != metaData);

            _sink         = sink;
            _getters      = getters;
            _ordinal      = ordinal;
            _readPosition = 0;
            _metaData     = metaData;
        }
        internal SmiSettersStream(SmiEventSink_Default sink, ITypedSettersV3 setters, int ordinal, SmiMetaData metaData)
        {
            Debug.Assert(null != sink);
            Debug.Assert(null != setters);
            Debug.Assert(0 <= ordinal);
            Debug.Assert(null != metaData);

            _sink          = sink;
            _setters       = setters;
            _ordinal       = ordinal;
            _lengthWritten = 0;
            _metaData      = metaData;
        }
        internal static SqlSequentialTextReaderSmi GetSequentialTextReader(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData)
        {
            Debug.Assert(!ValueUtilsSmi.IsDBNull_Unchecked(sink, getters, ordinal), "Should not try to get a SqlSequentialTextReaderSmi on a null column");
            ThrowIfITypedGettersIsNull(sink, getters, ordinal);
            if (!CanAccessGetterDirectly(metaData, ExtendedClrTypeCode.TextReader))
            {
                throw ADP.InvalidCast();
            }

            // This will advance the column to ordinal
            long length = GetCharsLength_Unchecked(sink, getters, ordinal);

            return(new SqlSequentialTextReaderSmi(sink, getters, ordinal, length));
        }
Beispiel #12
0
        internal void CleanMessages()
        {
            SmiEventSink_Default parent = (SmiEventSink_Default)_parent;

            if (null != parent)
            {
                parent.CleanMessages();
            }
            else
            {
                _errors   = null;
                _warnings = null;
            }
        }
        // calling GetTimeSpan on possibly v100 SMI
        internal static TimeSpan GetTimeSpan(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, bool gettersSupportKatmaiDateTime)
        {
            if (gettersSupportKatmaiDateTime)
            {
                return(GetTimeSpan(sink, (SmiTypedGetterSetter)getters, ordinal, metaData));
            }
            ThrowIfITypedGettersIsNull(sink, getters, ordinal);
            object obj = GetValue(sink, getters, ordinal, metaData, null);

            if (null == obj)
            {
                throw ADP.InvalidCast();
            }
            return((TimeSpan)obj);
        }
Beispiel #14
0
        //  SqlDataRecord public API
        /// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/ctor/*' />
        public SqlDataRecord(params SqlMetaData[] metaData)
        {
            // Initial consistency check
            if (metaData == null)
            {
                throw ADP.ArgumentNull(nameof(metaData));
            }

            _columnMetaData    = new SqlMetaData[metaData.Length];
            _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
#if NETFRAMEWORK
            ulong smiVersion = SmiVersion;
#endif
            for (int i = 0; i < _columnSmiMetaData.Length; i++)
            {
                if (metaData[i] == null)
                {
                    throw ADP.ArgumentNull($"{nameof(metaData)}[{i}]");
                }
                _columnMetaData[i]    = metaData[i];
                _columnSmiMetaData[i] = MetaDataUtilsSmi.SqlMetaDataToSmiExtendedMetaData(_columnMetaData[i]);
#if NETFRAMEWORK
                if (!MetaDataUtilsSmi.IsValidForSmiVersion(_columnSmiMetaData[i], smiVersion))
                {
                    throw ADP.VersionDoesNotSupportDataType(_columnSmiMetaData[i].TypeName);
                }
#endif
            }

            _eventSink = new SmiEventSink_Default();
#if NETFRAMEWORK
            if (InOutOfProcHelper.InProc)
            {
                _recordContext           = SmiContextFactory.Instance.GetCurrentContext();
                _recordBuffer            = _recordContext.CreateRecordBuffer(_columnSmiMetaData, _eventSink);
                _usesStringStorageForXml = false;
            }
            else
            {
                _recordContext           = null;
                _recordBuffer            = new MemoryRecordBuffer(_columnSmiMetaData);
                _usesStringStorageForXml = true;
            }
#else
            _recordBuffer = new MemoryRecordBuffer(_columnSmiMetaData);
            _eventSink.ProcessMessagesAndThrow();
#endif
        }
Beispiel #15
0
        internal SqlDataRecord(SmiRecordBuffer recordBuffer, params SmiExtendedMetaData[] metaData)
        {
            Debug.Assert(recordBuffer != null, "invalid attempt to instantiate SqlDataRecord with null SmiRecordBuffer");
            Debug.Assert(metaData != null, "invalid attempt to instantiate SqlDataRecord with null SmiExtendedMetaData[]");

            _columnMetaData    = new SqlMetaData[metaData.Length];
            _columnSmiMetaData = new SmiExtendedMetaData[metaData.Length];
            for (int i = 0; i < _columnSmiMetaData.Length; i++)
            {
                _columnSmiMetaData[i] = metaData[i];
                _columnMetaData[i]    = MetaDataUtilsSmi.SmiExtendedMetaDataToSqlMetaData(_columnSmiMetaData[i]);
            }

            _eventSink    = new SmiEventSink_Default();
            _recordBuffer = recordBuffer;
            _eventSink.ProcessMessagesAndThrow();
        }
        // spool a Stream into a scratch stream from the Smi interface and return it as a SqlStreamChars
        internal static SqlStreamChars CopyIntoNewSmiScratchStreamChars(Stream source, SmiEventSink_Default sink, SmiContext context)
        {
            SqlClientWrapperSmiStreamChars dest = new(sink, context.GetScratchStream(sink));

            int chunkSize;

            if (source.CanSeek && __maxByteChunkSize > source.Length)
            {
                chunkSize = unchecked ((int)source.Length);  // unchecked cast is safe due to check on line above
            }
            else
            {
                chunkSize = __maxByteChunkSize;
            }

            byte[] copyBuffer = new byte[chunkSize];
            int    bytesRead;

            while (0 != (bytesRead = source.Read(copyBuffer, 0, chunkSize)))
            {
                dest.Write(copyBuffer, 0, bytesRead);
            }
            dest.Flush();

            // SQLBU 494334
            //  Need to re-wind scratch stream to beginning before returning
            dest.Seek(0, SeekOrigin.Begin);

            return(dest);
        }
 internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record)
 {
     FillCompatibleITypedSettersFromRecord(sink, setters, metaData, record, null);
 }
        // UDTs and null variants come back via return value, all else is via targetBuffer.
        //  implements SqlClient 2.0-compatible output parameter semantics
        internal static object GetOutputParameterV3Smi(
            SmiEventSink_Default sink,  // event sink for errors
            ITypedGettersV3 getters,    // getters interface to grab value from
            int ordinal,                // parameter within getters
            SmiMetaData metaData,       // Getter's type for this ordinal
            SmiContext context,         // used to obtain scratch streams
            SqlBuffer targetBuffer      // destination
            )
        {
            object result = null;   // Workaround for UDT hack in non-Smi code paths.

            if (IsDBNull_Unchecked(sink, getters, ordinal))
            {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
            }
            else
            {
                switch (metaData.SqlDbType)
                {
                case SqlDbType.BigInt:
                    targetBuffer.Int64 = GetInt64_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.Binary:
                case SqlDbType.Image:
                case SqlDbType.Timestamp:
                case SqlDbType.VarBinary:
                    targetBuffer.SqlBinary = GetSqlBinary_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.Bit:
                    targetBuffer.Boolean = GetBoolean_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Char:
                case SqlDbType.VarChar:
                case SqlDbType.Text:
                    targetBuffer.SetToString(GetString_Unchecked(sink, getters, ordinal));
                    break;

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                {
                    SqlDateTime dt = new(GetDateTime_Unchecked(sink, getters, ordinal));
                    targetBuffer.SetToDateTime(dt.DayTicks, dt.TimeTicks);
                    break;
                }

                case SqlDbType.Decimal:
                {
                    SqlDecimal dec = GetSqlDecimal_Unchecked(sink, getters, ordinal);
                    targetBuffer.SetToDecimal(dec.Precision, dec.Scale, dec.IsPositive, dec.Data);
                    break;
                }

                case SqlDbType.Float:
                    targetBuffer.Double = GetDouble_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.Int:
                    targetBuffer.Int32 = GetInt32_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    targetBuffer.SetToMoney(GetInt64_Unchecked(sink, getters, ordinal));
                    break;

                case SqlDbType.Real:
                    targetBuffer.Single = GetSingle_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.UniqueIdentifier:
                    targetBuffer.SqlGuid = new SqlGuid(GetGuid_Unchecked(sink, getters, ordinal));
                    break;

                case SqlDbType.SmallInt:
                    targetBuffer.Int16 = GetInt16_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.TinyInt:
                    targetBuffer.Byte = GetByte_Unchecked(sink, getters, ordinal);
                    break;

                case SqlDbType.Variant:
                    // For variants, recur using the current value's sqldbtype
                    metaData = getters.GetVariantType(sink, ordinal);
                    sink.ProcessMessagesAndThrow();
                    Debug.Assert(SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!");
                    GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    break;

                case SqlDbType.Udt:
                    result = GetUdt_LengthChecked(sink, getters, ordinal, metaData);
                    break;

                case SqlDbType.Xml:
                    targetBuffer.SqlXml = GetSqlXml_Unchecked(sink, getters, ordinal, null);
                    break;

                default:
                    Debug.Assert(false, "Unexpected SqlDbType");
                    break;
                }
            }

            return(result);
        }
        internal static void FillCompatibleITypedSettersFromRecord(SmiEventSink_Default sink, ITypedSettersV3 setters, SmiMetaData[] metaData, SqlDataRecord record, SmiDefaultFieldsProperty useDefaultValues)
        {
            for (int i = 0; i < metaData.Length; ++i)
            {
                if (null != useDefaultValues && useDefaultValues[i])
                {
                    continue;
                }
                if (record.IsDBNull(i))
                {
                    ValueUtilsSmi.SetDBNull_Unchecked(sink, setters, i);
                }
                else
                {
                    switch (metaData[i].SqlDbType)
                    {
                    case SqlDbType.BigInt:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int64));
                        SetInt64_Unchecked(sink, setters, i, record.GetInt64(i));
                        break;

                    case SqlDbType.Binary:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
                        SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.Bit:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Boolean));
                        SetBoolean_Unchecked(sink, setters, i, record.GetBoolean(i));
                        break;

                    case SqlDbType.Char:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
                        SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.DateTime:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
                        SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i));
                        break;

                    case SqlDbType.Decimal:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlDecimal));
                        SetSqlDecimal_Unchecked(sink, setters, i, record.GetSqlDecimal(i));
                        break;

                    case SqlDbType.Float:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Double));
                        SetDouble_Unchecked(sink, setters, i, record.GetDouble(i));
                        break;

                    case SqlDbType.Image:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
                        SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.Int:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int32));
                        SetInt32_Unchecked(sink, setters, i, record.GetInt32(i));
                        break;

                    case SqlDbType.Money:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
                        SetSqlMoney_Unchecked(sink, setters, i, metaData[i], record.GetSqlMoney(i));
                        break;

                    case SqlDbType.NChar:
                    case SqlDbType.NText:
                    case SqlDbType.NVarChar:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
                        SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.Real:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Single));
                        SetSingle_Unchecked(sink, setters, i, record.GetFloat(i));
                        break;

                    case SqlDbType.UniqueIdentifier:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Guid));
                        SetGuid_Unchecked(sink, setters, i, record.GetGuid(i));
                        break;

                    case SqlDbType.SmallDateTime:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.DateTime));
                        SetDateTime_Checked(sink, setters, i, metaData[i], record.GetDateTime(i));
                        break;

                    case SqlDbType.SmallInt:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Int16));
                        SetInt16_Unchecked(sink, setters, i, record.GetInt16(i));
                        break;

                    case SqlDbType.SmallMoney:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlMoney));
                        SetSqlMoney_Checked(sink, setters, i, metaData[i], record.GetSqlMoney(i));
                        break;

                    case SqlDbType.Text:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlChars));
                        SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.Timestamp:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
                        SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.TinyInt:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.Byte));
                        SetByte_Unchecked(sink, setters, i, record.GetByte(i));
                        break;

                    case SqlDbType.VarBinary:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
                        SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.VarChar:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.String));
                        SetChars_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    case SqlDbType.Xml:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlXml));
                        SetSqlXml_Unchecked(sink, setters, i, record.GetSqlXml(i));        // perf improvement?
                        break;

                    case SqlDbType.Variant:
                        object o = record.GetSqlValue(i);
                        ExtendedClrTypeCode typeCode = MetaDataUtilsSmi.DetermineExtendedTypeCode(o);
                        SetCompatibleValue(sink, setters, i, metaData[i], o, typeCode, 0);
                        break;

                    case SqlDbType.Udt:
                        Debug.Assert(CanAccessSetterDirectly(metaData[i], ExtendedClrTypeCode.SqlBytes));
                        SetBytes_FromRecord(sink, setters, i, metaData[i], record, 0);
                        break;

                    default:
                        Debug.Assert(false, "unsupported DbType:" + metaData[i].SqlDbType.ToString());
                        throw ADP.NotSupported();
                    }
                }
            }
        }