private SqlBuffer(SqlBuffer value) { this._isNull = value._isNull; this._type = value._type; this._value = value._value; this._object = value._object; }
internal static SqlBuffer[] CreateBufferArray(int length) { SqlBuffer[] bufferArray = new SqlBuffer[length]; for (int i = 0; i < bufferArray.Length; i++) { bufferArray[i] = new SqlBuffer(); } return(bufferArray); }
internal static SqlBuffer[] CloneBufferArray(SqlBuffer[] values) { SqlBuffer[] bufferArray = new SqlBuffer[values.Length]; for (int i = 0; i < values.Length; i++) { bufferArray[i] = new SqlBuffer(values[i]); } return bufferArray; }
internal static SqlBuffer[] CreateBufferArray(int length) { SqlBuffer[] bufferArray = new SqlBuffer[length]; for (int i = 0; i < bufferArray.Length; i++) { bufferArray[i] = new SqlBuffer(); } return bufferArray; }
internal static SqlBuffer[] CreateBufferArray(int length) { SqlBuffer[] buffers = new SqlBuffer[length]; for (int i = 0; i < buffers.Length; ++i) { buffers[i] = new SqlBuffer(); } return(buffers); }
internal static SqlBuffer[] CloneBufferArray(SqlBuffer[] values) { SqlBuffer[] copy = new SqlBuffer[values.Length]; for (int i = 0; i < values.Length; i++) { copy[i] = new SqlBuffer(values[i]); } return(copy); }
private SqlBuffer(SqlBuffer value) { // Clone // value types _isNull = value._isNull; _type = value._type; // ref types - should also be read only unless at some point we allow this data // to be mutable, then we will need to copy _value = value._value; _object = value._object; }
internal static void Clear(SqlBuffer[] values) { if (values != null) { for (int i = 0; i < values.Length; i++) { values[i].Clear(); } } }
private bool TryReadSqlStringValue(SqlBuffer value, byte type, int length, Encoding encoding, bool isPlp, TdsParserStateObject stateObj) { switch (type) { case TdsEnums.SQLCHAR: case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: // If bigvarchar(max), we only read the first chunk here, // expecting the caller to read the rest if (encoding == null) { // if hitting 7.0 server, encoding will be null in metadata for columns or return values since // 7.0 has no support for multiple code pages in data - single code page support only encoding = _defaultEncoding; } string stringValue; if (!stateObj.TryReadStringWithEncoding(length, encoding, isPlp, out stringValue)) { return false; } value.SetToString(stringValue); break; case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: { String s = null; if (isPlp) { char[] cc = null; if (!TryReadPlpUnicodeChars(ref cc, 0, length >> 1, stateObj, out length)) { return false; } if (length > 0) { s = new String(cc, 0, length); } else { s = ADP.StrEmpty; } } else { if (!stateObj.TryReadString(length >> 1, out s)) { return false; } } value.SetToString(s); break; } default: Debug.Assert(false, "Unknown tds type for SqlString!" + type.ToString(CultureInfo.InvariantCulture)); break; } return true; }
internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, TdsParserStateObject stateObj) { bool isPlp = md.metaType.IsPlp; byte tdsType = md.tdsType; Debug.Assert(isPlp || !IsNull(md.metaType, (ulong)length), "null value should not get here!"); if (isPlp) { // We must read the column value completely, no matter what length is passed in length = Int32.MaxValue; } switch (tdsType) { case TdsEnums.SQLDECIMALN: case TdsEnums.SQLNUMERICN: if (!TryReadSqlDecimal(value, length, md.precision, md.scale, stateObj)) { return false; } break; case TdsEnums.SQLUDT: throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString()); case TdsEnums.SQLBINARY: case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLVARBINARY: case TdsEnums.SQLIMAGE: byte[] b = null; // If varbinary(max), we only read the first chunk here, expecting the caller to read the rest if (isPlp) { // If we are given -1 for length, then we read the entire value, // otherwise only the requested amount, usually first chunk. int ignored; if (!stateObj.TryReadPlpBytes(ref b, 0, length, out ignored)) { return false; } } else { //Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column"); b = new byte[length]; if (!stateObj.TryReadByteArray(b, 0, length)) { return false; } } value.SqlBinary = new SqlBinary(b, true); // doesn't copy the byte array break; case TdsEnums.SQLCHAR: case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: if (!TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj)) { return false; } break; case TdsEnums.SQLXMLTYPE: // We store SqlCachedBuffer here, so that we can return either SqlBinary, SqlString or SqlXmlReader. SqlCachedBuffer sqlBuf; if (!SqlCachedBuffer.TryCreate(md, this, stateObj, out sqlBuf)) { return false; } value.SqlCachedBuffer = sqlBuf; break; case TdsEnums.SQLDATE: case TdsEnums.SQLTIME: case TdsEnums.SQLDATETIME2: case TdsEnums.SQLDATETIMEOFFSET: if (!TryReadSqlDateTime(value, tdsType, length, md.scale, stateObj)) { return false; } break; default: Debug.Assert(!isPlp, "ReadSqlValue calling ReadSqlValueInternal with plp data"); if (!TryReadSqlValueInternal(value, tdsType, length, stateObj)) { return false; } break; } Debug.Assert((stateObj._longlen == 0) && (stateObj._longlenleft == 0), "ReadSqlValue did not read plp field completely, longlen =" + stateObj._longlen.ToString((IFormatProvider)null) + ",longlenleft=" + stateObj._longlenleft.ToString((IFormatProvider)null)); return true; }
// Used internally by BulkCopy only private bool TryProcessRow(_SqlMetaDataSet columns, object[] buffer, int[] map, TdsParserStateObject stateObj) { SqlBuffer data = new SqlBuffer(); for (int i = 0; i < columns.Length; i++) { _SqlMetaData md = columns[i]; Debug.Assert(md != null, "_SqlMetaData should not be null for column " + i.ToString(CultureInfo.InvariantCulture)); bool isNull; ulong len; if (!TryProcessColumnHeader(md, stateObj, i, out isNull, out len)) { return false; } if (isNull) { GetNullSqlValue(data, md); buffer[map[i]] = data.SqlValue; } else { // We only read up to 2Gb. Throw if data is larger. Very large data // should be read in chunks in sequential read mode // For Plp columns, we may have gotten only the length of the first chunk if (!TryReadSqlValue(data, md, md.metaType.IsPlp ? (Int32.MaxValue) : (int)len, stateObj)) { return false; } buffer[map[i]] = data.SqlValue; if (stateObj._longlen != 0) { throw new SqlTruncateException(Res.GetString(Res.SqlMisc_TruncationMaxDataMessage)); } } data.Clear(); } return true; }
internal object GetNullSqlValue(SqlBuffer nullVal, SqlMetaDataPriv md) { switch (md.type) { case SqlDbType.Real: nullVal.SetToNullOfType(SqlBuffer.StorageType.Single); break; case SqlDbType.Float: nullVal.SetToNullOfType(SqlBuffer.StorageType.Double); break; case SqlDbType.Udt: case SqlDbType.Binary: case SqlDbType.VarBinary: case SqlDbType.Image: nullVal.SqlBinary = SqlBinary.Null; break; case SqlDbType.UniqueIdentifier: nullVal.SqlGuid = SqlGuid.Null; break; case SqlDbType.Bit: nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean); break; case SqlDbType.TinyInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte); break; case SqlDbType.SmallInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16); break; case SqlDbType.Int: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32); break; case SqlDbType.BigInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64); break; case SqlDbType.Char: case SqlDbType.VarChar: case SqlDbType.NChar: case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.NText: nullVal.SetToNullOfType(SqlBuffer.StorageType.String); break; case SqlDbType.Decimal: nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal); break; case SqlDbType.DateTime: case SqlDbType.SmallDateTime: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime); break; case SqlDbType.Money: case SqlDbType.SmallMoney: nullVal.SetToNullOfType(SqlBuffer.StorageType.Money); break; case SqlDbType.Variant: // DBNull.Value will have to work here nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty); break; case SqlDbType.Xml: nullVal.SqlCachedBuffer = SqlCachedBuffer.Null; break; case SqlDbType.Date: nullVal.SetToNullOfType(SqlBuffer.StorageType.Date); break; case SqlDbType.Time: nullVal.SetToNullOfType(SqlBuffer.StorageType.Time); break; case SqlDbType.DateTime2: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2); break; case SqlDbType.DateTimeOffset: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset); break; case SqlDbType.Timestamp: break; default: Debug.Assert(false, "unknown null sqlType!" + md.type.ToString()); break; } return nullVal; }
// 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 SqlDateTime( 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 bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, TdsParserStateObject stateObj, SqlCommandColumnEncryptionSetting columnEncryptionOverride, string columnName) { bool isPlp = md.metaType.IsPlp; byte tdsType = md.tdsType; Debug.Assert(isPlp || !IsNull(md.metaType, (ulong)length), "null value should not get here!"); if (isPlp) { // We must read the column value completely, no matter what length is passed in length = Int32.MaxValue; } //DEVNOTE: When modifying the following routines (for deserialization) please pay attention to // deserialization code in DecryptWithKey () method and modify it accordingly. switch (tdsType) { case TdsEnums.SQLDECIMALN: case TdsEnums.SQLNUMERICN: if (!TryReadSqlDecimal(value, length, md.precision, md.scale, stateObj)) { return false; } break; case TdsEnums.SQLUDT: case TdsEnums.SQLBINARY: case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLVARBINARY: case TdsEnums.SQLIMAGE: byte[] b = null; // If varbinary(max), we only read the first chunk here, expecting the caller to read the rest if (isPlp) { // If we are given -1 for length, then we read the entire value, // otherwise only the requested amount, usually first chunk. int ignored; if (!stateObj.TryReadPlpBytes(ref b, 0, length, out ignored)) { return false; } } else { //Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column"); b = new byte[length]; if (!stateObj.TryReadByteArray(b, 0, length)) { return false; } } if (md.isEncrypted && ((columnEncryptionOverride == SqlCommandColumnEncryptionSetting.Enabled || columnEncryptionOverride == SqlCommandColumnEncryptionSetting.ResultSetOnly) || (columnEncryptionOverride == SqlCommandColumnEncryptionSetting.UseConnectionSetting && _connHandler != null && _connHandler.ConnectionOptions != null && _connHandler.ConnectionOptions.ColumnEncryptionSetting == SqlConnectionColumnEncryptionSetting.Enabled))) { try { // CipherInfo is present, decrypt and read byte[] unencryptedBytes = SqlSecurityUtility.DecryptWithKey(b, md.cipherMD, _connHandler.ConnectionOptions.DataSource); if (unencryptedBytes != null) { DeserializeUnencryptedValue(value, unencryptedBytes, md, stateObj, md.NormalizationRuleVersion); } } catch (Exception e) { throw SQL.ColumnDecryptionFailed(columnName, null, e); } } else { value.SqlBinary = new SqlBinary(b, true); // doesn't copy the byte array } break; case TdsEnums.SQLCHAR: case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: if (!TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj)) { return false; } break; case TdsEnums.SQLXMLTYPE: // We store SqlCachedBuffer here, so that we can return either SqlBinary, SqlString or SqlXmlReader. SqlCachedBuffer sqlBuf; if (!SqlCachedBuffer.TryCreate(md, this, stateObj, out sqlBuf)) { return false; } value.SqlCachedBuffer = sqlBuf; break; case TdsEnums.SQLDATE: case TdsEnums.SQLTIME: case TdsEnums.SQLDATETIME2: case TdsEnums.SQLDATETIMEOFFSET: if (!TryReadSqlDateTime(value, tdsType, length, md.scale, stateObj)) { return false; } break; default: Debug.Assert(!isPlp, "ReadSqlValue calling ReadSqlValueInternal with plp data"); if (!TryReadSqlValueInternal(value, tdsType, length, stateObj)) { return false; } break; } Debug.Assert((stateObj._longlen == 0) && (stateObj._longlenleft == 0), "ReadSqlValue did not read plp field completely, longlen =" + stateObj._longlen.ToString((IFormatProvider)null) + ",longlenleft=" + stateObj._longlenleft.ToString((IFormatProvider)null)); return true; }
internal static void Clear(SqlBuffer[] values) { if (null != values) { for (int i = 0; i < values.Length; ++i) { values[i].Clear(); } } }
private bool TryReadSqlDateTime(SqlBuffer value, byte tdsType, int length, byte scale, TdsParserStateObject stateObj) { byte[] datetimeBuffer = new byte[length]; if (!stateObj.TryReadByteArray(datetimeBuffer, 0, length)) { return false; } switch (tdsType) { case TdsEnums.SQLDATE: Debug.Assert(length == 3, "invalid length for date type!"); value.SetToDate(datetimeBuffer); break; case TdsEnums.SQLTIME: Debug.Assert(3 <= length && length <= 5, "invalid length for time type!"); value.SetToTime(datetimeBuffer, length, scale); break; case TdsEnums.SQLDATETIME2: Debug.Assert(6 <= length && length <= 8, "invalid length for datetime2 type!"); value.SetToDateTime2(datetimeBuffer, length, scale); break; case TdsEnums.SQLDATETIMEOFFSET: Debug.Assert(8 <= length && length <= 10, "invalid length for datetimeoffset type!"); value.SetToDateTimeOffset(datetimeBuffer, length, scale); break; default: Debug.Assert(false, "ReadSqlDateTime is called with the wrong tdsType"); break; } return true; }
// // Read in a SQLVariant // // SQLVariant looks like: // struct // { // BYTE TypeTag // BYTE cbPropBytes // BYTE[] Properties // BYTE[] DataVal // } internal bool TryReadSqlVariant(SqlBuffer value, int lenTotal, TdsParserStateObject stateObj) { // get the SQLVariant type byte type; if (!stateObj.TryReadByte(out type)) { return false; } ushort lenMax = 0; // maximum lenData of value inside variant // read cbPropBytes byte cbPropsActual; if (!stateObj.TryReadByte(out cbPropsActual)) { return false; } MetaType mt = MetaType.GetSqlDataType(type, 0 /*no user datatype*/, 0 /* no lenData, non-nullable type */); byte cbPropsExpected = mt.PropBytes; int lenConsumed = TdsEnums.SQLVARIANT_SIZE + cbPropsActual; // type, count of propBytes, and actual propBytes int lenData = lenTotal - lenConsumed; // length of actual data // read known properties and skip unknown properties Debug.Assert(cbPropsActual >= cbPropsExpected, "cbPropsActual is less that cbPropsExpected!"); // // now read the value // switch (type) { case TdsEnums.SQLBIT: case TdsEnums.SQLINT1: case TdsEnums.SQLINT2: case TdsEnums.SQLINT4: case TdsEnums.SQLINT8: case TdsEnums.SQLFLT4: case TdsEnums.SQLFLT8: case TdsEnums.SQLMONEY: case TdsEnums.SQLMONEY4: case TdsEnums.SQLDATETIME: case TdsEnums.SQLDATETIM4: case TdsEnums.SQLUNIQUEID: if (!TryReadSqlValueInternal(value, type, lenData, stateObj)) { return false; } break; case TdsEnums.SQLDECIMALN: case TdsEnums.SQLNUMERICN: { Debug.Assert(cbPropsExpected == 2, "SqlVariant: invalid PropBytes for decimal/numeric type!"); byte precision; if (!stateObj.TryReadByte(out precision)) { return false; } byte scale; if (!stateObj.TryReadByte(out scale)) { return false; } // skip over unknown properties if (cbPropsActual > cbPropsExpected) { if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected)) { return false; } } if (!TryReadSqlDecimal(value, TdsEnums.MAX_NUMERIC_LEN, precision, scale, stateObj)) { return false; } break; } case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: //Debug.Assert(TdsEnums.VARNULL == lenData, "SqlVariant: data length for Binary indicates null?"); Debug.Assert(cbPropsExpected == 2, "SqlVariant: invalid PropBytes for binary type!"); if (!stateObj.TryReadUInt16(out lenMax)) { return false; } Debug.Assert(lenMax != TdsEnums.SQL_USHORTVARMAXLEN, "bigvarbinary(max) in a sqlvariant"); // skip over unknown properties if (cbPropsActual > cbPropsExpected) { if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected)) { return false; } } goto case TdsEnums.SQLBIT; case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: { Debug.Assert(cbPropsExpected == 7, "SqlVariant: invalid PropBytes for character type!"); SqlCollation collation; if (!TryProcessCollation(stateObj, out collation)) { return false; } if (!stateObj.TryReadUInt16(out lenMax)) { return false; } Debug.Assert(lenMax != TdsEnums.SQL_USHORTVARMAXLEN, "bigvarchar(max) or nvarchar(max) in a sqlvariant"); // skip over unknown properties if (cbPropsActual > cbPropsExpected) { if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected)) { return false; } } Encoding encoding = Encoding.GetEncoding(GetCodePage(collation, stateObj)); if (!TryReadSqlStringValue(value, type, lenData, encoding, false, stateObj)) { return false; } break; } case TdsEnums.SQLDATE: if (!TryReadSqlDateTime(value, type, lenData, 0, stateObj)) { return false; } break; case TdsEnums.SQLTIME: case TdsEnums.SQLDATETIME2: case TdsEnums.SQLDATETIMEOFFSET: { Debug.Assert(cbPropsExpected == 1, "SqlVariant: invalid PropBytes for time/datetime2/datetimeoffset type!"); byte scale; if (!stateObj.TryReadByte(out scale)) { return false; } // skip over unknown properties if (cbPropsActual > cbPropsExpected) { if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected)) { return false; } } if (!TryReadSqlDateTime(value, type, lenData, scale, stateObj)) { return false; } break; } default: Debug.Assert(false, "Unknown tds type in SqlVariant!" + type.ToString(CultureInfo.InvariantCulture)); break; } // switch return true; }
private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result) { if (SqlDbType.Udt == metaData.SqlDbType) { result = NullUdtInstance(metaData); } else { SqlBuffer.StorageType storageType = __dbTypeToStorageType[(int) metaData.SqlDbType]; if (storageType == SqlBuffer.StorageType.Empty) { result = DBNull.Value; } else if (SqlBuffer.StorageType.SqlBinary == storageType) { targetBuffer.SqlBinary = SqlBinary.Null; } else if (SqlBuffer.StorageType.SqlGuid == storageType) { targetBuffer.SqlGuid = SqlGuid.Null; } else { targetBuffer.SetToNullOfType(storageType); } } }
internal static object GetOutputParameterV200Smi(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal, SmiMetaData metaData, SmiContext context, SqlBuffer targetBuffer) { object result = null; if (IsDBNull_Unchecked(sink, getters, ordinal)) { GetNullOutputParameterSmi(metaData, targetBuffer, ref result); return result; } switch (metaData.SqlDbType) { case SqlDbType.Date: targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal)); return result; case SqlDbType.Time: targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale); return result; case SqlDbType.DateTime2: targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale); return result; case SqlDbType.DateTimeOffset: targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale); return result; case SqlDbType.Variant: metaData = getters.GetVariantType(sink, ordinal); sink.ProcessMessagesAndThrow(); GetOutputParameterV200Smi(sink, getters, ordinal, metaData, context, targetBuffer); return result; } return GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer); }
internal void OnParameterAvailableSmi(SmiParameterMetaData metaData, ITypedGettersV3 parameterValues, int ordinal) { if (ParameterDirection.Input != metaData.Direction) { string paramName = null; if (ParameterDirection.ReturnValue != metaData.Direction) { paramName = metaData.Name; } SqlParameterCollection currentParameterCollection = this.GetCurrentParameterCollection(); int parameterCount = this.GetParameterCount(currentParameterCollection); SqlParameter parameter = this.GetParameterForOutputValueExtraction(currentParameterCollection, paramName, parameterCount); if (parameter != null) { object obj2; parameter.LocaleId = (int) metaData.LocaleId; parameter.CompareInfo = metaData.CompareOptions; SqlBuffer targetBuffer = new SqlBuffer(); if (this._activeConnection.IsKatmaiOrNewer) { obj2 = ValueUtilsSmi.GetOutputParameterV200Smi(this.OutParamEventSink, (SmiTypedGetterSetter) parameterValues, ordinal, metaData, this._smiRequestContext, targetBuffer); } else { obj2 = ValueUtilsSmi.GetOutputParameterV3Smi(this.OutParamEventSink, parameterValues, ordinal, metaData, this._smiRequestContext, targetBuffer); } if (obj2 != null) { parameter.Value = obj2; } else { parameter.SetSqlBuffer(targetBuffer); } } } }
internal void SetSqlBuffer(SqlBuffer buff) { _sqlBufferReturnValue = buff; _value = null; _coercedValue = null; _isNull = _sqlBufferReturnValue.IsNull; _coercedValueIsDataFeed = false; _coercedValueIsSqlType = false; _actualSize = -1; }
internal static object GetOutputParameterV3Smi(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, SmiContext context, SqlBuffer targetBuffer) { object result = null; if (IsDBNull_Unchecked(sink, getters, ordinal)) { GetNullOutputParameterSmi(metaData, targetBuffer, ref result); return result; } switch (metaData.SqlDbType) { case SqlDbType.BigInt: targetBuffer.Int64 = GetInt64_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Binary: case SqlDbType.Image: case SqlDbType.Timestamp: case SqlDbType.VarBinary: targetBuffer.SqlBinary = GetSqlBinary_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Bit: targetBuffer.Boolean = GetBoolean_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Char: case SqlDbType.NChar: case SqlDbType.NText: case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.VarChar: targetBuffer.SetToString(GetString_Unchecked(sink, getters, ordinal)); return result; case SqlDbType.DateTime: case SqlDbType.SmallDateTime: { SqlDateTime time = new SqlDateTime(GetDateTime_Unchecked(sink, getters, ordinal)); targetBuffer.SetToDateTime(time.DayTicks, time.TimeTicks); return result; } case SqlDbType.Decimal: { SqlDecimal num = GetSqlDecimal_Unchecked(sink, getters, ordinal); targetBuffer.SetToDecimal(num.Precision, num.Scale, num.IsPositive, num.Data); return result; } case SqlDbType.Float: targetBuffer.Double = GetDouble_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Int: targetBuffer.Int32 = GetInt32_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Money: case SqlDbType.SmallMoney: targetBuffer.SetToMoney(GetInt64_Unchecked(sink, getters, ordinal)); return result; case SqlDbType.Real: targetBuffer.Single = GetSingle_Unchecked(sink, getters, ordinal); return result; case SqlDbType.UniqueIdentifier: targetBuffer.SqlGuid = new SqlGuid(GetGuid_Unchecked(sink, getters, ordinal)); return result; case SqlDbType.SmallInt: targetBuffer.Int16 = GetInt16_Unchecked(sink, getters, ordinal); return result; case SqlDbType.TinyInt: targetBuffer.Byte = GetByte_Unchecked(sink, getters, ordinal); return result; case SqlDbType.Variant: metaData = getters.GetVariantType(sink, ordinal); sink.ProcessMessagesAndThrow(); GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer); return result; case (SqlDbType.SmallInt | SqlDbType.Int): case (SqlDbType.Text | SqlDbType.Int): case (SqlDbType.Xml | SqlDbType.Bit): case (SqlDbType.TinyInt | SqlDbType.Int): return result; case SqlDbType.Xml: targetBuffer.SqlXml = GetSqlXml_Unchecked(sink, getters, ordinal, null); return result; case SqlDbType.Udt: return GetUdt_LengthChecked(sink, getters, ordinal, metaData); } return result; }
internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, TdsParserStateObject stateObj) { switch (tdsType) { case TdsEnums.SQLBIT: case TdsEnums.SQLBITN: Debug.Assert(length == 1, "invalid length for SqlBoolean type!"); byte byteValue; if (!stateObj.TryReadByte(out byteValue)) { return false; } value.Boolean = (byteValue != 0); break; case TdsEnums.SQLINTN: if (length == 1) { goto case TdsEnums.SQLINT1; } else if (length == 2) { goto case TdsEnums.SQLINT2; } else if (length == 4) { goto case TdsEnums.SQLINT4; } else { goto case TdsEnums.SQLINT8; } case TdsEnums.SQLINT1: Debug.Assert(length == 1, "invalid length for SqlByte type!"); if (!stateObj.TryReadByte(out byteValue)) { return false; } value.Byte = byteValue; break; case TdsEnums.SQLINT2: Debug.Assert(length == 2, "invalid length for SqlInt16 type!"); short shortValue; if (!stateObj.TryReadInt16(out shortValue)) { return false; } value.Int16 = shortValue; break; case TdsEnums.SQLINT4: Debug.Assert(length == 4, "invalid length for SqlInt32 type!"); int intValue; if (!stateObj.TryReadInt32(out intValue)) { return false; } value.Int32 = intValue; break; case TdsEnums.SQLINT8: Debug.Assert(length == 8, "invalid length for SqlInt64 type!"); long longValue; if (!stateObj.TryReadInt64(out longValue)) { return false; } value.Int64 = longValue; break; case TdsEnums.SQLFLTN: if (length == 4) { goto case TdsEnums.SQLFLT4; } else { goto case TdsEnums.SQLFLT8; } case TdsEnums.SQLFLT4: Debug.Assert(length == 4, "invalid length for SqlSingle type!"); float singleValue; if (!stateObj.TryReadSingle(out singleValue)) { return false; } value.Single = singleValue; break; case TdsEnums.SQLFLT8: Debug.Assert(length == 8, "invalid length for SqlDouble type!"); double doubleValue; if (!stateObj.TryReadDouble(out doubleValue)) { return false; } value.Double = doubleValue; break; case TdsEnums.SQLMONEYN: if (length == 4) { goto case TdsEnums.SQLMONEY4; } else { goto case TdsEnums.SQLMONEY; } case TdsEnums.SQLMONEY: { int mid; uint lo; if (!stateObj.TryReadInt32(out mid)) { return false; } if (!stateObj.TryReadUInt32(out lo)) { return false; } long l = (((long)mid) << 0x20) + ((long)lo); value.SetToMoney(l); break; } case TdsEnums.SQLMONEY4: if (!stateObj.TryReadInt32(out intValue)) { return false; } value.SetToMoney(intValue); break; case TdsEnums.SQLDATETIMN: if (length == 4) { goto case TdsEnums.SQLDATETIM4; } else { goto case TdsEnums.SQLDATETIME; } case TdsEnums.SQLDATETIM4: ushort daypartShort, timepartShort; if (!stateObj.TryReadUInt16(out daypartShort)) { return false; } if (!stateObj.TryReadUInt16(out timepartShort)) { return false; } value.SetToDateTime(daypartShort, timepartShort * SqlDateTime.SQLTicksPerMinute); break; case TdsEnums.SQLDATETIME: int daypart; uint timepart; if (!stateObj.TryReadInt32(out daypart)) { return false; } if (!stateObj.TryReadUInt32(out timepart)) { return false; } value.SetToDateTime(daypart, (int)timepart); break; case TdsEnums.SQLUNIQUEID: { Debug.Assert(length == 16, "invalid length for SqlGuid type!"); byte[] b = new byte[length]; if (!stateObj.TryReadByteArray(b, 0, length)) { return false; } value.SqlGuid = new SqlGuid(b, true); // doesn't copy the byte array break; } case TdsEnums.SQLBINARY: case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLVARBINARY: case TdsEnums.SQLIMAGE: { // Note: Better not come here with plp data!! Debug.Assert(length <= TdsEnums.MAXSIZE); byte[] b = new byte[length]; if (!stateObj.TryReadByteArray(b, 0, length)) { return false; } value.SqlBinary = new SqlBinary(b, true); // doesn't copy the byte array break; } case TdsEnums.SQLVARIANT: if (!TryReadSqlVariant(value, length, stateObj)) { return false; } break; default: Debug.Assert(false, "Unknown SqlType!" + tdsType.ToString(CultureInfo.InvariantCulture)); break; } // switch return true; }
internal static object GetNullSqlValue( SqlBuffer nullVal, SqlMetaDataPriv md, SqlCommandColumnEncryptionSetting columnEncryptionSetting, SqlInternalConnectionTds connection) { SqlDbType type = md.type; if (type == SqlDbType.VarBinary && // if its a varbinary md.isEncrypted &&// and encrypted ShouldHonorTceForRead(columnEncryptionSetting, connection)){ type = md.baseTI.type; // the use the actual (plaintext) type } switch (type) { case SqlDbType.Real: nullVal.SetToNullOfType(SqlBuffer.StorageType.Single); break; case SqlDbType.Float: nullVal.SetToNullOfType(SqlBuffer.StorageType.Double); break; case SqlDbType.Udt: case SqlDbType.Binary: case SqlDbType.VarBinary: case SqlDbType.Image: nullVal.SqlBinary = SqlBinary.Null; break; case SqlDbType.UniqueIdentifier: nullVal.SqlGuid = SqlGuid.Null; break; case SqlDbType.Bit: nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean); break; case SqlDbType.TinyInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte); break; case SqlDbType.SmallInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16); break; case SqlDbType.Int: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32); break; case SqlDbType.BigInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64); break; case SqlDbType.Char: case SqlDbType.VarChar: case SqlDbType.NChar: case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.NText: nullVal.SetToNullOfType(SqlBuffer.StorageType.String); break; case SqlDbType.Decimal: nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal); break; case SqlDbType.DateTime: case SqlDbType.SmallDateTime: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime); break; case SqlDbType.Money: case SqlDbType.SmallMoney: nullVal.SetToNullOfType(SqlBuffer.StorageType.Money); break; case SqlDbType.Variant: // DBNull.Value will have to work here nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty); break; case SqlDbType.Xml: nullVal.SqlCachedBuffer = SqlCachedBuffer.Null; break; case SqlDbType.Date: nullVal.SetToNullOfType(SqlBuffer.StorageType.Date); break; case SqlDbType.Time: nullVal.SetToNullOfType(SqlBuffer.StorageType.Time); break; case SqlDbType.DateTime2: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2); break; case SqlDbType.DateTimeOffset: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset); break; case SqlDbType.Timestamp: // Dev10 Bug #479607 - this should have been the same as SqlDbType.Binary, but it's a rejected breaking change // Dev10 Bug #752790 - don't assert when it does happen break; default: Debug.Assert(false, "unknown null sqlType!" + md.type.ToString()); break; } return nullVal; }
private bool TryReadSqlDecimal(SqlBuffer value, int length, byte precision, byte scale, TdsParserStateObject stateObj) { byte byteValue; if (!stateObj.TryReadByte(out byteValue)) { return false; } bool fPositive = (1 == byteValue); length = checked((int)length - 1); int[] bits; if (!TryReadDecimalBits(length, stateObj, out bits)) { return false; } value.SetToDecimal(precision, scale, fPositive, bits); return true; }
// VSTFDevDiv#479681 - Data corruption when sending Katmai Date types to the server via TVP // Ensures proper handling on DateTime2 sub type for Sql_Variants and TVPs. internal static void SetCompatibleValueV200( SmiEventSink_Default sink, SmiTypedGetterSetter setters, int ordinal, SmiMetaData metaData, object value, ExtendedClrTypeCode typeCode, int offset, int length, ParameterPeekAheadValue peekAhead, SqlBuffer.StorageType storageType ) { // Ensure caller validated compatibility for types handled directly in this method Debug.Assert((ExtendedClrTypeCode.DataTable != typeCode && ExtendedClrTypeCode.DbDataReader != typeCode && ExtendedClrTypeCode.IEnumerableOfSqlDataRecord != typeCode) || CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType); if (typeCode == ExtendedClrTypeCode.DateTime) { if (storageType == SqlBuffer.StorageType.DateTime2) SetDateTime2_Checked(sink, setters, ordinal, metaData, (DateTime)value); else if (storageType == SqlBuffer.StorageType.Date) SetDate_Checked(sink, setters, ordinal, metaData, (DateTime)value); else SetDateTime_Checked(sink, setters, ordinal, metaData, (DateTime)value); } else { SetCompatibleValueV200(sink, setters, ordinal, metaData, value, typeCode, offset, length, peekAhead); } }
internal static SqlBuffer[] CreateBufferArray(int length) { SqlBuffer[] buffers = new SqlBuffer[length]; for (int i = 0; i < buffers.Length; ++i) { buffers[i] = new SqlBuffer(); } return buffers; }
internal void SetSqlBuffer(SqlBuffer buff) { this._sqlBufferReturnValue = buff; this._value = null; this._coercedValue = null; this._udtLoadError = null; }
private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result) { if (SqlDbType.Udt == metaData.SqlDbType) { result = NullUdtInstance(metaData); } else { SqlBuffer.StorageType stype = SqlDbTypeToStorageType(metaData.SqlDbType); if ( SqlBuffer.StorageType.Empty == stype ) { result = DBNull.Value; } else if (SqlBuffer.StorageType.SqlBinary == stype) { // special case SqlBinary, 'cause tds parser never sets SqlBuffer to null, just to empty! targetBuffer.SqlBinary = SqlBinary.Null; } else if (SqlBuffer.StorageType.SqlGuid == stype) { targetBuffer.SqlGuid = SqlGuid.Null; } else { targetBuffer.SetToNullOfType( stype ); } } }
internal SqlReturnValue() : base() { value = new SqlBuffer(); }
// 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; }
/// <summary> /// Deserializes the unencrypted bytes into a value based on the target type info. /// </summary> internal bool DeserializeUnencryptedValue (SqlBuffer value, byte[] unencryptedBytes, SqlMetaDataPriv md, TdsParserStateObject stateObj, byte normalizationVersion) { if (normalizationVersion != 0x01) { throw SQL.UnsupportedNormalizationVersion(normalizationVersion); } byte tdsType = md.baseTI.tdsType; int length = unencryptedBytes.Length; // For normalized types, the length and scale of the actual type might be different than the value's. int denormalizedLength = md.baseTI.length; byte denormalizedScale = md.baseTI.scale; Debug.Assert (false == md.baseTI.isEncrypted, "Double encryption detected"); switch (tdsType) { // We normalize to allow conversion across data types. All data types below are serialized into a BIGINT. case TdsEnums.SQLBIT: case TdsEnums.SQLBITN: case TdsEnums.SQLINTN: case TdsEnums.SQLINT1: case TdsEnums.SQLINT2: case TdsEnums.SQLINT4: case TdsEnums.SQLINT8: Debug.Assert(length == 8, "invalid length for SqlInt64 type!"); byte byteValue; long longValue; if (unencryptedBytes.Length != 8) { return false; } longValue = BitConverter.ToInt64(unencryptedBytes, 0); if (tdsType == TdsEnums.SQLBIT || tdsType == TdsEnums.SQLBITN) { value.Boolean = (longValue != 0); break; } if (tdsType == TdsEnums.SQLINT1 || denormalizedLength == 1) value.Byte = (byte)longValue; else if (tdsType == TdsEnums.SQLINT2 || denormalizedLength == 2) value.Int16 = (Int16)longValue; else if (tdsType == TdsEnums.SQLINT4 || denormalizedLength == 4) value.Int32 = (Int32)longValue; else value.Int64 = longValue; break; case TdsEnums.SQLFLTN: if (length == 4) { goto case TdsEnums.SQLFLT4; } else { goto case TdsEnums.SQLFLT8; } case TdsEnums.SQLFLT4: Debug.Assert(length == 4, "invalid length for SqlSingle type!"); float singleValue; if (unencryptedBytes.Length != 4) { return false; } singleValue = BitConverter.ToSingle(unencryptedBytes, 0); value.Single = singleValue; break; case TdsEnums.SQLFLT8: double doubleValue; if (unencryptedBytes.Length != 8) { return false; } doubleValue = BitConverter.ToDouble(unencryptedBytes, 0); value.Double = doubleValue; break; // We normalize to allow conversion across data types. SMALLMONEY is serialized into a MONEY. case TdsEnums.SQLMONEYN: case TdsEnums.SQLMONEY4: case TdsEnums.SQLMONEY: { int mid; uint lo; if (unencryptedBytes.Length != 8) { return false; } mid = BitConverter.ToInt32(unencryptedBytes, 0); lo = BitConverter.ToUInt32(unencryptedBytes, 4); long l = (((long)mid) << 0x20) + ((long)lo); value.SetToMoney(l); break; } case TdsEnums.SQLDATETIMN: if (length == 4) { goto case TdsEnums.SQLDATETIM4; } else { goto case TdsEnums.SQLDATETIME; } case TdsEnums.SQLDATETIM4: ushort daypartShort, timepartShort; if (unencryptedBytes.Length != 4) { return false; } daypartShort = (UInt16)((unencryptedBytes[1] << 8) + unencryptedBytes[0]); timepartShort = (UInt16)((unencryptedBytes[3] << 8) + unencryptedBytes[2]); value.SetToDateTime(daypartShort, timepartShort * SqlDateTime.SQLTicksPerMinute); break; case TdsEnums.SQLDATETIME: int daypart; uint timepart; if (unencryptedBytes.Length != 8) { return false; } daypart = BitConverter.ToInt32(unencryptedBytes, 0); timepart = BitConverter.ToUInt32(unencryptedBytes, 4); value.SetToDateTime(daypart, (int)timepart); break; case TdsEnums.SQLUNIQUEID: { Debug.Assert(length == 16, "invalid length for SqlGuid type!"); value.SqlGuid = new SqlGuid(unencryptedBytes, true); // doesn't copy the byte array break; } case TdsEnums.SQLBINARY: case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLVARBINARY: case TdsEnums.SQLIMAGE: { // Note: Better not come here with plp data!! Debug.Assert(length <= TdsEnums.MAXSIZE, "Plp data decryption attempted"); // If this is a fixed length type, pad with zeros to get to the fixed length size. if (tdsType == TdsEnums.SQLBINARY || tdsType == TdsEnums.SQLBIGBINARY) { byte[] bytes = new byte[md.baseTI.length]; Buffer.BlockCopy(unencryptedBytes, 0, bytes, 0, unencryptedBytes.Length); unencryptedBytes = bytes; } value.SqlBinary = new SqlBinary(unencryptedBytes, true); // doesn't copy the byte array break; } case TdsEnums.SQLDECIMALN: case TdsEnums.SQLNUMERICN: // Check the sign from the first byte. int index = 0; byteValue = unencryptedBytes[index++]; bool fPositive = (1 == byteValue); // Now read the 4 next integers which contain the actual value. length = checked((int)length-1); int[] bits = new int[4]; int decLength = length>>2; for (int i = 0; i < decLength; i++) { // up to 16 bytes of data following the sign byte bits[i] = BitConverter.ToInt32(unencryptedBytes, index); index += 4; } value.SetToDecimal (md.baseTI.precision, md.baseTI.scale, fPositive, bits); break; case TdsEnums.SQLCHAR: case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLVARCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: { System.Text.Encoding encoding = md.baseTI.encoding; if (null == encoding) { encoding = _defaultEncoding; } if (null == encoding) { ThrowUnsupportedCollationEncountered(stateObj); } string strValue = encoding.GetString(unencryptedBytes, 0, length); // If this is a fixed length type, pad with spaces to get to the fixed length size. if (tdsType == TdsEnums.SQLCHAR || tdsType == TdsEnums.SQLBIGCHAR) { strValue = strValue.PadRight(md.baseTI.length); } value.SetToString(strValue); break; } case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: { string strValue = System.Text.Encoding.Unicode.GetString(unencryptedBytes, 0, length); // If this is a fixed length type, pad with spaces to get to the fixed length size. if (tdsType == TdsEnums.SQLNCHAR) { strValue = strValue.PadRight(md.baseTI.length / ADP.CharSize); } value.SetToString(strValue); break; } case TdsEnums.SQLDATE: Debug.Assert(length == 3, "invalid length for date type!"); value.SetToDate(unencryptedBytes); break; case TdsEnums.SQLTIME: // We normalize to maximum precision to allow conversion across different precisions. Debug.Assert(length == 5, "invalid length for time type!"); value.SetToTime(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale); break; case TdsEnums.SQLDATETIME2: // We normalize to maximum precision to allow conversion across different precisions. Debug.Assert(length == 8, "invalid length for datetime2 type!"); value.SetToDateTime2(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale); break; case TdsEnums.SQLDATETIMEOFFSET: // We normalize to maximum precision to allow conversion across different precisions. Debug.Assert(length == 10, "invalid length for datetimeoffset type!"); value.SetToDateTimeOffset(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale); break; default: MetaType metaType = md.baseTI.metaType; // If we don't have a metatype already, construct one to get the proper type name. if (metaType == null) { metaType = MetaType.GetSqlDataType(tdsType, userType:0, length:length); } throw SQL.UnsupportedDatatypeEncryption(metaType.TypeName); } return true; }
internal object GetNullSqlValue(SqlBuffer nullVal, SqlMetaDataPriv md) { switch (md.type) { case SqlDbType.BigInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64); return nullVal; case SqlDbType.Binary: case SqlDbType.Image: case SqlDbType.VarBinary: case SqlDbType.Udt: nullVal.SqlBinary = SqlBinary.Null; return nullVal; case SqlDbType.Bit: nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean); return nullVal; case SqlDbType.Char: case SqlDbType.NChar: case SqlDbType.NText: case SqlDbType.NVarChar: case SqlDbType.Text: case SqlDbType.VarChar: nullVal.SetToNullOfType(SqlBuffer.StorageType.String); return nullVal; case SqlDbType.DateTime: case SqlDbType.SmallDateTime: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime); return nullVal; case SqlDbType.Decimal: nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal); return nullVal; case SqlDbType.Float: nullVal.SetToNullOfType(SqlBuffer.StorageType.Double); return nullVal; case SqlDbType.Int: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32); return nullVal; case SqlDbType.Money: case SqlDbType.SmallMoney: nullVal.SetToNullOfType(SqlBuffer.StorageType.Money); return nullVal; case SqlDbType.Real: nullVal.SetToNullOfType(SqlBuffer.StorageType.Single); return nullVal; case SqlDbType.UniqueIdentifier: nullVal.SqlGuid = SqlGuid.Null; return nullVal; case SqlDbType.SmallInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16); return nullVal; case SqlDbType.Timestamp: case (SqlDbType.SmallInt | SqlDbType.Int): case (SqlDbType.Text | SqlDbType.Int): case (SqlDbType.Xml | SqlDbType.Bit): case (SqlDbType.TinyInt | SqlDbType.Int): case SqlDbType.Structured: return nullVal; case SqlDbType.TinyInt: nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte); return nullVal; case SqlDbType.Variant: nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty); return nullVal; case SqlDbType.Xml: nullVal.SqlCachedBuffer = SqlCachedBuffer.Null; return nullVal; case SqlDbType.Date: nullVal.SetToNullOfType(SqlBuffer.StorageType.Date); return nullVal; case SqlDbType.Time: nullVal.SetToNullOfType(SqlBuffer.StorageType.Time); return nullVal; case SqlDbType.DateTime2: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2); return nullVal; case SqlDbType.DateTimeOffset: nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset); return nullVal; } return nullVal; }