Inheritance: SqlMetaDataPriv
 internal _SqlMetaDataSet(int count)
 {
     _metaDataArray = new _SqlMetaData[count];
     for (int i = 0; i < _metaDataArray.Length; ++i)
     {
         _metaDataArray[i] = new _SqlMetaData(i);
     }
 }
Example #2
0
        private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col)
        {
            byte byteLen;
            UInt32 userType;

            // read user type - 4 bytes Yukon, 2 backwards
            if (!stateObj.TryReadUInt32(out userType))
            {
                return false;
            }

            // read flags and set appropriate flags in structure
            byte flags;
            if (!stateObj.TryReadByte(out flags))
            {
                return false;
            }

            col.updatability = (byte)((flags & TdsEnums.Updatability) >> 2);
            col.isNullable = (TdsEnums.Nullable == (flags & TdsEnums.Nullable));
            col.isIdentity = (TdsEnums.Identity == (flags & TdsEnums.Identity));

            // read second byte of column metadata flags
            if (!stateObj.TryReadByte(out flags))
            {
                return false;
            }


            byte tdsType;
            if (!stateObj.TryReadByte(out tdsType))
            {
                return false;
            }

            if (tdsType == TdsEnums.SQLXMLTYPE)
                col.length = TdsEnums.SQL_USHORTVARMAXLEN;  //Use the same length as other plp datatypes
            else if (IsVarTimeTds(tdsType))
                col.length = 0;  // placeholder until we read the scale, just make sure it's not SQL_USHORTVARMAXLEN
            else if (tdsType == TdsEnums.SQLDATE)
            {
                col.length = 3;
            }
            else
            {
                if (!TryGetTokenLength(tdsType, stateObj, out col.length))
                {
                    return false;
                }
            }

            col.metaType = MetaType.GetSqlDataType(tdsType, userType, col.length);
            col.type = col.metaType.SqlDbType;

            col.tdsType = (col.isNullable ? col.metaType.NullableType : col.metaType.TDSType);

            {
                if (TdsEnums.SQLUDT == tdsType)
                {
                    throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString());
                }

                if (col.length == TdsEnums.SQL_USHORTVARMAXLEN)
                {
                    Debug.Assert(tdsType == TdsEnums.SQLXMLTYPE ||
                                 tdsType == TdsEnums.SQLBIGVARCHAR ||
                                 tdsType == TdsEnums.SQLBIGVARBINARY ||
                                 tdsType == TdsEnums.SQLNVARCHAR ||
                                 tdsType == TdsEnums.SQLUDT,
                                 "Invalid streaming datatype");
                    col.metaType = MetaType.GetMaxMetaTypeFromMetaType(col.metaType);
                    Debug.Assert(col.metaType.IsLong, "Max datatype not IsLong");
                    col.length = Int32.MaxValue;
                    if (tdsType == TdsEnums.SQLXMLTYPE)
                    {
                        byte schemapresent;
                        if (!stateObj.TryReadByte(out schemapresent))
                        {
                            return false;
                        }

                        if ((schemapresent & 1) != 0)
                        {
                            if (!stateObj.TryReadByte(out byteLen))
                            {
                                return false;
                            }
                            if (byteLen != 0)
                            {
                                if (!stateObj.TryReadString(byteLen, out col.xmlSchemaCollectionDatabase))
                                {
                                    return false;
                                }
                            }

                            if (!stateObj.TryReadByte(out byteLen))
                            {
                                return false;
                            }
                            if (byteLen != 0)
                            {
                                if (!stateObj.TryReadString(byteLen, out col.xmlSchemaCollectionOwningSchema))
                                {
                                    return false;
                                }
                            }

                            short shortLen;
                            if (!stateObj.TryReadInt16(out shortLen))
                            {
                                return false;
                            }
                            if (byteLen != 0)
                            {
                                if (!stateObj.TryReadString(shortLen, out col.xmlSchemaCollectionName))
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }

            if (col.type == SqlDbType.Decimal)
            {
                if (!stateObj.TryReadByte(out col.precision))
                {
                    return false;
                }
                if (!stateObj.TryReadByte(out col.scale))
                {
                    return false;
                }
            }

            if (col.metaType.IsVarTime)
            {
                if (!stateObj.TryReadByte(out col.scale))
                {
                    return false;
                }

                Debug.Assert(0 <= col.scale && col.scale <= 7);

                // calculate actual column length here
                switch (col.metaType.SqlDbType)
                {
                    case SqlDbType.Time:
                        col.length = MetaType.GetTimeSizeFromScale(col.scale);
                        break;
                    case SqlDbType.DateTime2:
                        // Date in number of days (3 bytes) + time
                        col.length = 3 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;
                    case SqlDbType.DateTimeOffset:
                        // Date in days (3 bytes) + offset in minutes (2 bytes) + time
                        col.length = 5 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;

                    default:
                        Debug.Assert(false, "Unknown VariableTime type!");
                        break;
                }
            }

            // read the collation for 7.x servers
            if (col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE))
            {
                if (!TryProcessCollation(stateObj, out col.collation))
                {
                    return false;
                }

                int codePage = GetCodePage(col.collation, stateObj);

                if (codePage == _defaultCodePage)
                {
                    col.codePage = _defaultCodePage;
                    col.encoding = _defaultEncoding;
                }
                else
                {
                    col.codePage = codePage;
                    col.encoding = System.Text.Encoding.GetEncoding(col.codePage);
                }
            }

            if (col.metaType.IsLong && !col.metaType.IsPlp)
            {
                int unusedLen = 0xFFFF;      //We ignore this value
                if (!TryProcessOneTable(stateObj, ref unusedLen, out col.multiPartTableName))
                {
                    return false;
                }
            }

            if (!stateObj.TryReadByte(out byteLen))
            {
                return false;
            }
            if (!stateObj.TryReadString(byteLen, out col.column))
            {
                return false;
            }

            // We get too many DONE COUNTs from the server, causing too meany StatementCompleted event firings.
            // We only need to fire this event when we actually have a meta data stream with 0 or more rows.
            stateObj._receivedColMetaData = true;
            return true;
        }
 internal _SqlMetaDataSet(int count, SqlTceCipherInfoTable? cipherTable) {
     cekTable = cipherTable;
     metaDataArray = new _SqlMetaData[count];
     for(int i = 0; i < metaDataArray.Length; ++i) {
         metaDataArray[i] = new _SqlMetaData(i);
     }
 }
 public object Clone()
 {
     _SqlMetaData result = new _SqlMetaData(ordinal);
     result.CopyFrom(this);
     result.column = column;
     result.multiPartTableName = multiPartTableName;
     result.updatability = updatability;
     result.isKey = isKey;
     result.isHidden = isHidden;
     result.isIdentity = isIdentity;
     return result;
 }
 internal _ColumnMapping(int columnId, _SqlMetaData metadata)
 {
     this._sourceColumnOrdinal = columnId;
     this._metadata = metadata;
 }
 public object Clone() {
     _SqlMetaData result = new _SqlMetaData(ordinal);
     result.CopyFrom(this);
     result.column = column;
     result.baseColumn = baseColumn;
     result.multiPartTableName = multiPartTableName;
     result.updatability = updatability;
     result.tableNum = tableNum;
     result.isDifferentName = isDifferentName;
     result.isKey = isKey;
     result.isHidden = isHidden;
     result.isExpression = isExpression;
     result.isIdentity = isIdentity;
     result.isColumnSet = isColumnSet;
     result.op = op;
     result.operand = operand;
     return result;
 }
        private object GetValueFromSourceRow(int columnOrdinal, _SqlMetaData metadata, int[] UseSqlValue, int destRowIndex)
        {
            if (UseSqlValue[destRowIndex] == 0)
            {
                UseSqlValue[destRowIndex] = -1;
                if ((metadata.metaType.NullableType == 0x6a) || (metadata.metaType.NullableType == 0x6c))
                {
                    Type fieldType = null;
                    switch (this._rowSourceType)
                    {
                        case ValueSourceType.IDataReader:
                            if (this._SqlDataReaderRowSource != null)
                            {
                                fieldType = this._SqlDataReaderRowSource.GetFieldType(columnOrdinal);
                            }
                            break;

                        case ValueSourceType.DataTable:
                        case ValueSourceType.RowArray:
                            fieldType = this._currentRow.Table.Columns[columnOrdinal].DataType;
                            break;
                    }
                    if ((typeof(SqlDecimal) == fieldType) || (typeof(decimal) == fieldType))
                    {
                        UseSqlValue[destRowIndex] = 4;
                    }
                    else if ((typeof(SqlDouble) == fieldType) || (typeof(double) == fieldType))
                    {
                        UseSqlValue[destRowIndex] = 5;
                    }
                    else if ((typeof(SqlSingle) == fieldType) || (typeof(float) == fieldType))
                    {
                        UseSqlValue[destRowIndex] = 10;
                    }
                }
            }
            switch (this._rowSourceType)
            {
                case ValueSourceType.IDataReader:
                    if (this._SqlDataReaderRowSource == null)
                    {
                        return ((IDataReader) this._rowSource).GetValue(columnOrdinal);
                    }
                    switch (UseSqlValue[destRowIndex])
                    {
                        case 4:
                            return this._SqlDataReaderRowSource.GetSqlDecimal(columnOrdinal);

                        case 5:
                            return new SqlDecimal(this._SqlDataReaderRowSource.GetSqlDouble(columnOrdinal).Value);

                        case 10:
                            return new SqlDecimal((double) this._SqlDataReaderRowSource.GetSqlSingle(columnOrdinal).Value);
                    }
                    return this._SqlDataReaderRowSource.GetValue(columnOrdinal);

                case ValueSourceType.DataTable:
                case ValueSourceType.RowArray:
                {
                    object obj2 = this._currentRow[columnOrdinal];
                    if (((obj2 == null) || (DBNull.Value == obj2)) || (((10 != UseSqlValue[destRowIndex]) && (5 != UseSqlValue[destRowIndex])) && (4 != UseSqlValue[destRowIndex])))
                    {
                        return obj2;
                    }
                    INullable nullable = obj2 as INullable;
                    if ((nullable != null) && nullable.IsNull)
                    {
                        return obj2;
                    }
                    SqlBuffer.StorageType type2 = (SqlBuffer.StorageType) UseSqlValue[destRowIndex];
                    switch (type2)
                    {
                        case SqlBuffer.StorageType.Decimal:
                            if (nullable == null)
                            {
                                return new SqlDecimal((decimal) obj2);
                            }
                            return (SqlDecimal) obj2;

                        case SqlBuffer.StorageType.Double:
                        {
                            if (nullable == null)
                            {
                                double d = (double) obj2;
                                if (double.IsNaN(d))
                                {
                                    return obj2;
                                }
                                return new SqlDecimal(d);
                            }
                            SqlDouble num4 = (SqlDouble) obj2;
                            return new SqlDecimal(num4.Value);
                        }
                    }
                    if (type2 != SqlBuffer.StorageType.Single)
                    {
                        return obj2;
                    }
                    if (nullable != null)
                    {
                        SqlSingle num5 = (SqlSingle) obj2;
                        return new SqlDecimal((double) num5.Value);
                    }
                    float f = (float) obj2;
                    if (float.IsNaN(f))
                    {
                        return obj2;
                    }
                    return new SqlDecimal((double) f);
                }
            }
            throw ADP.NotSupported();
        }
Example #8
0
 internal SqlDbColumn(_SqlMetaData md)
 {
     _metadata = md;
     Populate();
 }
Example #9
0
        /// <summary>
        /// Writes the crypto metadata (as part of COLMETADATA token) for encrypted columns.
        /// </summary>
        /// <returns></returns>
        internal void WriteCryptoMetadata(_SqlMetaData md, TdsParserStateObject stateObj) {
            if (!_serverSupportsColumnEncryption || // TCE Feature supported
                !md.isEncrypted || // Column is not encrypted
                !ShouldEncryptValuesForBulkCopy()) { // TCE disabled on connection string
                return; 
            }

            // Write the ordinal
            WriteShort (md.cipherMD.CekTableOrdinal, stateObj);

            // Write UserType and TYPEINFO
            WriteTceUserTypeAndTypeInfo(md.baseTI, stateObj);

            // Write Encryption Algo
            stateObj.WriteByte(md.cipherMD.CipherAlgorithmId);

            if (TdsEnums.CustomCipherAlgorithmId == md.cipherMD.CipherAlgorithmId) {
                // Write the algorithm name
                Debug.Assert (md.cipherMD.CipherAlgorithmName.Length < 256);
                stateObj.WriteByte((byte)md.cipherMD.CipherAlgorithmName.Length);
                WriteString(md.cipherMD.CipherAlgorithmName, stateObj);
            }

            // Write Encryption Algo Type
            stateObj.WriteByte(md.cipherMD.EncryptionType);

            // Write Normalization Version
            stateObj.WriteByte(md.cipherMD.NormalizationRuleVersion);
        }
        private object ConvertValue(object value, _SqlMetaData metadata)
        {
            object obj2;
            if (ADP.IsNull(value))
            {
                if (!metadata.isNullable)
                {
                    throw SQL.BulkLoadBulkLoadNotAllowDBNull(metadata.column);
                }
                return value;
            }
            MetaType metaType = metadata.metaType;
            try
            {
                MetaType metaTypeFromSqlDbType;
                SqlDecimal num2;
                switch (metaType.NullableType)
                {
                    case 0x22:
                    case 0x23:
                    case 0x24:
                    case 0x26:
                    case 40:
                    case 0x29:
                    case 0x2a:
                    case 0x2b:
                    case 50:
                    case 0x3a:
                    case 0x3b:
                    case 0x3d:
                    case 0x3e:
                    case 0x68:
                    case 0x6d:
                    case 110:
                    case 0x6f:
                    case 0xa5:
                    case 0xa7:
                    case 0xad:
                    case 0xaf:
                        metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false);
                        value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType);
                        goto Label_0290;

                    case 0x62:
                        value = this.ValidateBulkCopyVariant(value);
                        goto Label_0290;

                    case 0x63:
                    case 0xef:
                    case 0xe7:
                    {
                        metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false);
                        value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType);
                        int num3 = (value is string) ? ((string) value).Length : ((SqlString) value).Value.Length;
                        if (num3 > (metadata.length / 2))
                        {
                            throw SQL.BulkLoadStringTooLong();
                        }
                        goto Label_0290;
                    }
                    case 0x6a:
                    case 0x6c:
                        metaTypeFromSqlDbType = MetaType.GetMetaTypeFromSqlDbType(metaType.SqlDbType, false);
                        value = SqlParameter.CoerceValue(value, metaTypeFromSqlDbType);
                        if (!(value is SqlDecimal))
                        {
                            break;
                        }
                        num2 = (SqlDecimal) value;
                        goto Label_017D;

                    case 240:
                        if (value.GetType() != typeof(byte[]))
                        {
                            value = this._connection.GetBytes(value);
                        }
                        goto Label_0290;

                    case 0xf1:
                        if (value is XmlReader)
                        {
                            value = MetaType.GetStringFromXml((XmlReader) value);
                        }
                        goto Label_0290;

                    default:
                        throw SQL.BulkLoadCannotConvertValue(value.GetType(), metadata.metaType, null);
                }
                num2 = new SqlDecimal((decimal) value);
            Label_017D:
                if (num2.Scale != metadata.scale)
                {
                    num2 = TdsParser.AdjustSqlDecimalScale(num2, metadata.scale);
                    value = num2;
                }
                if (num2.Precision > metadata.precision)
                {
                    throw SQL.BulkLoadCannotConvertValue(value.GetType(), metaTypeFromSqlDbType, ADP.ParameterValueOutOfRange(num2));
                }
            Label_0290:
                obj2 = value;
            }
            catch (Exception exception)
            {
                if (!ADP.IsCatchableExceptionType(exception))
                {
                    throw;
                }
                throw SQL.BulkLoadCannotConvertValue(value.GetType(), metadata.metaType, exception);
            }
            return obj2;
        }
Example #11
0
        private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col, SqlTceCipherInfoTable? cipherTable, bool fColMD, SqlCommandColumnEncryptionSetting columnEncryptionSetting) {
            byte byteLen;
            UInt32 userType;

            // read user type - 4 bytes Yukon, 2 backwards
            if (IsYukonOrNewer) {
                if (!stateObj.TryReadUInt32(out userType)) {
                    return false;
                }
            }
            else {
                ushort userTypeShort;
                if (!stateObj.TryReadUInt16(out userTypeShort)) {
                    return false;
                }
                userType = userTypeShort;
            }

            // read flags and set appropriate flags in structure
            byte flags;
            if (!stateObj.TryReadByte(out flags)) {
                return false;
            }

            col.updatability = (byte)((flags & TdsEnums.Updatability) >> 2);
            col.isNullable = (TdsEnums.Nullable == (flags & TdsEnums.Nullable));
            col.isIdentity = (TdsEnums.Identity == (flags & TdsEnums.Identity));

            // read second byte of column metadata flags
            if (!stateObj.TryReadByte(out flags)) {
                return false;
            }
            
            col.isColumnSet = (TdsEnums.IsColumnSet == (flags & TdsEnums.IsColumnSet));
            if (fColMD && _serverSupportsColumnEncryption) {
                col.isEncrypted = (TdsEnums.IsEncrypted == (flags & TdsEnums.IsEncrypted));
            }

            // Read TypeInfo
            if (!TryProcessTypeInfo (stateObj, col, userType)) {
                return false;
            }

            // Read tablename if present
            if (col.metaType.IsLong && !col.metaType.IsPlp) {
                if (_isYukon) {
                    int  unusedLen = 0xFFFF;      //We ignore this value
                    if (!TryProcessOneTable(stateObj, ref unusedLen, out col.multiPartTableName)) {
                        return false;
                    }
                } else {
                    ushort shortLen;
                    if (!stateObj.TryReadUInt16(out shortLen)) {
                        return false;
                    }
                    string tableName;
                    if (!stateObj.TryReadString(shortLen, out tableName)) {
                        return false;
                    }
                    // with Sql2000 this is returned as an unquoted mix of catalog.owner.table
                    // all of which may contain "." and unable to parse correctly from the string alone
                    // example "select * from pubs..[A.B.C.D.E]" AND only when * will contain a image/text/ntext column
                    // by delay parsing from execute to SqlDataReader.GetSchemaTable to enable more scenarios
                    col.multiPartTableName = new MultiPartTableName(tableName);
                }
            }

            // Read the TCE column cryptoinfo
            if (fColMD && _serverSupportsColumnEncryption && col.isEncrypted) {
                // If the column is encrypted, we should have a valid cipherTable
                if (cipherTable.HasValue && !TryProcessTceCryptoMetadata (stateObj, col, cipherTable.Value, columnEncryptionSetting, isReturnValue: false)) {
                    return false;
                }
            }

            // Read the column name 
            if (!stateObj.TryReadByte(out byteLen)) {
                return false;
            }
            if (!stateObj.TryReadString(byteLen, out col.column)) {
                return false;
            }

            // We get too many DONE COUNTs from the server, causing too meany StatementCompleted event firings.
            // We only need to fire this event when we actually have a meta data stream with 0 or more rows.
            stateObj._receivedColMetaData = true;
            return true;
        }
 private string GetDataTypeNameInternal(_SqlMetaData metaData)
 {
     if ((this._typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005) && metaData.IsNewKatmaiDateTimeType)
     {
         return MetaType.MetaNVarChar.TypeName;
     }
     if ((this._typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005) && metaData.IsLargeUdt)
     {
         if (this._typeSystem == SqlConnectionString.TypeSystem.SQLServer2005)
         {
             return MetaType.MetaMaxVarBinary.TypeName;
         }
         return MetaType.MetaImage.TypeName;
     }
     if (this._typeSystem != SqlConnectionString.TypeSystem.SQLServer2000)
     {
         if (metaData.type == SqlDbType.Udt)
         {
             return (metaData.udtDatabaseName + "." + metaData.udtSchemaName + "." + metaData.udtTypeName);
         }
         return metaData.metaType.TypeName;
     }
     return this.GetVersionedMetaType(metaData.metaType).TypeName;
 }
 private Type GetProviderSpecificFieldTypeInternal(_SqlMetaData metaData)
 {
     if ((this._typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005) && metaData.IsNewKatmaiDateTimeType)
     {
         return MetaType.MetaNVarChar.SqlType;
     }
     if ((this._typeSystem <= SqlConnectionString.TypeSystem.SQLServer2005) && metaData.IsLargeUdt)
     {
         if (this._typeSystem == SqlConnectionString.TypeSystem.SQLServer2005)
         {
             return MetaType.MetaMaxVarBinary.SqlType;
         }
         return MetaType.MetaImage.SqlType;
     }
     if (this._typeSystem != SqlConnectionString.TypeSystem.SQLServer2000)
     {
         if (metaData.type == SqlDbType.Udt)
         {
             SqlConnection.CheckGetExtendedUDTInfo(metaData, false);
             return metaData.udtType;
         }
         return metaData.metaType.SqlType;
     }
     return this.GetVersionedMetaType(metaData.metaType).SqlType;
 }
Example #14
0
        private bool TryCommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col) {
            byte byteLen;
            UInt32 userType;

            // read user type - 4 bytes Yukon, 2 backwards
            if (IsYukonOrNewer) {
                if (!stateObj.TryReadUInt32(out userType)) {
                    return false;
                }
            }
            else {
                ushort userTypeShort;
                if (!stateObj.TryReadUInt16(out userTypeShort)) {
                    return false;
                }
                userType = userTypeShort;
            }

            // read flags and set appropriate flags in structure
            byte flags;
            if (!stateObj.TryReadByte(out flags)) {
                return false;
            }

            col.updatability = (byte)((flags & TdsEnums.Updatability) >> 2);
            col.isNullable = (TdsEnums.Nullable == (flags & TdsEnums.Nullable));
            col.isIdentity = (TdsEnums.Identity == (flags & TdsEnums.Identity));

            // read second byte of column metadata flags
            if (!stateObj.TryReadByte(out flags)) {
                return false;
            }
            
            col.isColumnSet = (TdsEnums.IsColumnSet == (flags & TdsEnums.IsColumnSet));

            byte tdsType;
            if (!stateObj.TryReadByte(out tdsType)) {
                return false;
            }

            if (tdsType == TdsEnums.SQLXMLTYPE)
                col.length = TdsEnums.SQL_USHORTVARMAXLEN;  //Use the same length as other plp datatypes
            else if (IsVarTimeTds(tdsType))
                col.length = 0;  // placeholder until we read the scale, just make sure it's not SQL_USHORTVARMAXLEN
            else if (tdsType == TdsEnums.SQLDATE) {
                col.length = 3;
            }
            else {
                if (!TryGetTokenLength(tdsType, stateObj, out col.length)) {
                    return false;
                }
            }

            col.metaType = MetaType.GetSqlDataType(tdsType, userType, col.length);
            col.type = col.metaType.SqlDbType;

            // If sphinx, do not change to nullable type
            if (_isShiloh)
                col.tdsType = (col.isNullable ? col.metaType.NullableType : col.metaType.TDSType);
            else
                col.tdsType = tdsType;

            if (_isYukon) {
                if (TdsEnums.SQLUDT == tdsType) {
                    if (!TryProcessUDTMetaData((SqlMetaDataPriv) col, stateObj)) {
                        return false;
                    }
                }

                if (col.length == TdsEnums.SQL_USHORTVARMAXLEN) {
                    Debug.Assert(tdsType == TdsEnums.SQLXMLTYPE ||
                                 tdsType == TdsEnums.SQLBIGVARCHAR ||
                                 tdsType == TdsEnums.SQLBIGVARBINARY ||
                                 tdsType == TdsEnums.SQLNVARCHAR ||
                                 tdsType == TdsEnums.SQLUDT,
                                 "Invalid streaming datatype");
                    col.metaType = MetaType.GetMaxMetaTypeFromMetaType(col.metaType);
                    Debug.Assert(col.metaType.IsLong, "Max datatype not IsLong");
                    col.length = Int32.MaxValue;
                    if (tdsType == TdsEnums.SQLXMLTYPE) {
                        byte schemapresent;
                        if (!stateObj.TryReadByte(out schemapresent)) {
                            return false;
                        }

                        if ((schemapresent & 1) != 0) {
                            if (!stateObj.TryReadByte(out byteLen)) {
                                return false;
                            }
                            if (byteLen != 0) {
                                if (!stateObj.TryReadString(byteLen, out col.xmlSchemaCollectionDatabase)) {
                                    return false;
                                }
                            }

                            if (!stateObj.TryReadByte(out byteLen)) {
                                return false;
                            }
                            if (byteLen != 0) {
                                if (!stateObj.TryReadString(byteLen, out col.xmlSchemaCollectionOwningSchema)) {
                                    return false;
                                }
                            }

                            short shortLen;
                            if (!stateObj.TryReadInt16(out shortLen)) {
                                return false;
                            }
                            if (byteLen != 0) {
                                if (!stateObj.TryReadString(shortLen, out col.xmlSchemaCollectionName)) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }

            if (col.type == SqlDbType.Decimal) {
                if (!stateObj.TryReadByte(out col.precision)) {
                    return false;
                }
                if (!stateObj.TryReadByte(out col.scale)) {
                    return false;
                }
            }

            if (col.metaType.IsVarTime) {
                if (!stateObj.TryReadByte(out col.scale)) {
                    return false;
                }

                Debug.Assert(0 <= col.scale && col.scale <= 7);

                // calculate actual column length here
                // 
                switch (col.metaType.SqlDbType)
                {
                    case SqlDbType.Time:
                        col.length = MetaType.GetTimeSizeFromScale(col.scale);
                        break;
                    case SqlDbType.DateTime2:
                        // Date in number of days (3 bytes) + time
                        col.length = 3 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;
                    case SqlDbType.DateTimeOffset:
                        // Date in days (3 bytes) + offset in minutes (2 bytes) + time
                        col.length = 5 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;

                    default:
                        Debug.Assert(false, "Unknown VariableTime type!");
                        break;
                }
            }

            // read the collation for 7.x servers
            if (_isShiloh && col.metaType.IsCharType && (tdsType != TdsEnums.SQLXMLTYPE)) {
                if (!TryProcessCollation(stateObj, out col.collation)) {
                    return false;
                }

                int codePage = GetCodePage(col.collation, stateObj);

                if (codePage == _defaultCodePage) {
                    col.codePage = _defaultCodePage;
                    col.encoding = _defaultEncoding;
                }
                else {
                    col.codePage = codePage;
                    col.encoding = System.Text.Encoding.GetEncoding(col.codePage);
                }
            }

            if (col.metaType.IsLong && !col.metaType.IsPlp) {
                if (_isYukon) {
                    int  unusedLen = 0xFFFF;      //We ignore this value
                    if (!TryProcessOneTable(stateObj, ref unusedLen, out col.multiPartTableName)) {
                        return false;
                    }
                } else {
                    ushort shortLen;
                    if (!stateObj.TryReadUInt16(out shortLen)) {
                        return false;
                    }
                    string tableName;
                    if (!stateObj.TryReadString(shortLen, out tableName)) {
                        return false;
                    }
                    // with Sql2000 this is returned as an unquoted mix of catalog.owner.table
                    // all of which may contain "." and unable to parse correctly from the string alone
                    // example "select * from pubs..[A.B.C.D.E]" AND only when * will contain a image/text/ntext column
                    // by delay parsing from execute to SqlDataReader.GetSchemaTable to enable more scenarios
                    col.multiPartTableName = new MultiPartTableName(tableName);
                }
            }

            if (!stateObj.TryReadByte(out byteLen)) {
                return false;
            }
            if (!stateObj.TryReadString(byteLen, out col.column)) {
                return false;
            }

            // We get too many DONE COUNTs from the server, causing too meany StatementCompleted event firings.
            // We only need to fire this event when we actually have a meta data stream with 0 or more rows.
            stateObj._receivedColMetaData = true;
            return true;
        }
        private void CommonProcessMetaData(TdsParserStateObject stateObj, _SqlMetaData col)
        {
            uint num5;
            int length = 0;
            if (this.IsYukonOrNewer)
            {
                num5 = stateObj.ReadUInt32();
            }
            else
            {
                num5 = stateObj.ReadUInt16();
            }
            byte num3 = stateObj.ReadByte();
            col.updatability = (byte) ((num3 & 11) >> 2);
            col.isNullable = 1 == (num3 & 1);
            col.isIdentity = 0x10 == (num3 & 0x10);
            stateObj.ReadByte();
            col.isColumnSet = 4 == (num3 & 4);
            byte tdsType = stateObj.ReadByte();
            if (tdsType == 0xf1)
            {
                col.length = 0xffff;
            }
            else if (this.IsVarTimeTds(tdsType))
            {
                col.length = 0;
            }
            else if (tdsType == 40)
            {
                col.length = 3;
            }
            else
            {
                col.length = this.GetTokenLength(tdsType, stateObj);
            }
            col.metaType = MetaType.GetSqlDataType(tdsType, num5, col.length);
            col.type = col.metaType.SqlDbType;
            if (this._isShiloh)
            {
                col.tdsType = col.isNullable ? col.metaType.NullableType : col.metaType.TDSType;
            }
            else
            {
                col.tdsType = tdsType;
            }
            if (this._isYukon)
            {
                if (240 == tdsType)
                {
                    this.ProcessUDTMetaData(col, stateObj);
                }
                if (col.length == 0xffff)
                {
                    col.metaType = MetaType.GetMaxMetaTypeFromMetaType(col.metaType);
                    col.length = 0x7fffffff;
                    if ((tdsType == 0xf1) && ((stateObj.ReadByte() & 1) != 0))
                    {
                        length = stateObj.ReadByte();
                        if (length != 0)
                        {
                            col.xmlSchemaCollectionDatabase = stateObj.ReadString(length);
                        }
                        length = stateObj.ReadByte();
                        if (length != 0)
                        {
                            col.xmlSchemaCollectionOwningSchema = stateObj.ReadString(length);
                        }
                        length = stateObj.ReadInt16();
                        if (length != 0)
                        {
                            col.xmlSchemaCollectionName = stateObj.ReadString(length);
                        }
                    }
                }
            }
            if (col.type == SqlDbType.Decimal)
            {
                col.precision = stateObj.ReadByte();
                col.scale = stateObj.ReadByte();
            }
            if (col.metaType.IsVarTime)
            {
                col.scale = stateObj.ReadByte();
                switch (col.metaType.SqlDbType)
                {
                    case SqlDbType.Time:
                        col.length = MetaType.GetTimeSizeFromScale(col.scale);
                        break;

                    case SqlDbType.DateTime2:
                        col.length = 3 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;

                    case SqlDbType.DateTimeOffset:
                        col.length = 5 + MetaType.GetTimeSizeFromScale(col.scale);
                        break;
                }
            }
            if ((this._isShiloh && col.metaType.IsCharType) && (tdsType != 0xf1))
            {
                col.collation = this.ProcessCollation(stateObj);
                int codePage = this.GetCodePage(col.collation, stateObj);
                if (codePage == this._defaultCodePage)
                {
                    col.codePage = this._defaultCodePage;
                    col.encoding = this._defaultEncoding;
                }
                else
                {
                    col.codePage = codePage;
                    col.encoding = Encoding.GetEncoding(col.codePage);
                }
            }
            if (col.metaType.IsLong && !col.metaType.IsPlp)
            {
                if (this._isYukon)
                {
                    int num7 = 0xffff;
                    col.multiPartTableName = this.ProcessOneTable(stateObj, ref num7);
                }
                else
                {
                    length = stateObj.ReadUInt16();
                    string multipartName = stateObj.ReadString(length);
                    col.multiPartTableName = new MultiPartTableName(multipartName);
                }
            }
            length = stateObj.ReadByte();
            col.column = stateObj.ReadString(length);
            stateObj._receivedColMetaData = true;
        }