Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -4793,13 +4793,13 @@ internal TdsOperationStatus TryProcessReturnValue(int length,
{
return result;
}
if (rec.XmlSchemaCollection is null)
if (rec.XmlTypeInfo is null)
{
rec.XmlSchemaCollection = new SqlMetaDataXmlSchemaCollection();
rec.XmlTypeInfo = new TdsXmlTypeInfo();
}
if (len != 0)
{
result = stateObj.TryReadString(len, out rec.XmlSchemaCollection.Database);
result = stateObj.TryReadString(len, out rec.XmlTypeInfo.Database);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -4813,7 +4813,7 @@ internal TdsOperationStatus TryProcessReturnValue(int length,
}
if (len != 0)
{
result = stateObj.TryReadString(len, out rec.XmlSchemaCollection.OwningSchema);
result = stateObj.TryReadString(len, out rec.XmlTypeInfo.OwningSchema);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -4829,7 +4829,7 @@ internal TdsOperationStatus TryProcessReturnValue(int length,

if (slen != 0)
{
result = stateObj.TryReadString(slen, out rec.XmlSchemaCollection.Name);
result = stateObj.TryReadString(slen, out rec.XmlTypeInfo.Name);
if (result != TdsOperationStatus.Done)
{
return result;
Expand Down Expand Up @@ -5551,13 +5551,13 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Tds
{
return result;
}
if (col.XmlSchemaCollection is null)
if (col.XmlTypeInfo is null)
{
col.XmlSchemaCollection = new SqlMetaDataXmlSchemaCollection();
col.XmlTypeInfo = new TdsXmlTypeInfo();
}
if (byteLen != 0)
{
result = stateObj.TryReadString(byteLen, out col.XmlSchemaCollection.Database);
result = stateObj.TryReadString(byteLen, out col.XmlTypeInfo.Database);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -5571,7 +5571,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Tds
}
if (byteLen != 0)
{
result = stateObj.TryReadString(byteLen, out col.XmlSchemaCollection.OwningSchema);
result = stateObj.TryReadString(byteLen, out col.XmlTypeInfo.OwningSchema);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -5586,7 +5586,7 @@ private TdsOperationStatus TryProcessTypeInfo(TdsParserStateObject stateObj, Tds
}
if (byteLen != 0)
{
result = stateObj.TryReadString(shortLen, out col.XmlSchemaCollection.Name);
result = stateObj.TryReadString(shortLen, out col.XmlTypeInfo.Name);
if (result != TdsOperationStatus.Done)
{
return result;
Expand Down Expand Up @@ -5791,13 +5791,13 @@ private TdsOperationStatus TryProcessUDTMetaData(TdsTypeInfo metaData, TdsParser
{
return result;
}
if (metaData.Udt is null)
if (metaData.UdtTypeInfo is null)
{
metaData.Udt = new SqlMetaDataUdt();
metaData.UdtTypeInfo = new TdsUdtTypeInfo();
}
if (byteLength != 0)
{
result = stateObj.TryReadString(byteLength, out metaData.Udt.DatabaseName);
result = stateObj.TryReadString(byteLength, out metaData.UdtTypeInfo.DatabaseName);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -5812,7 +5812,7 @@ private TdsOperationStatus TryProcessUDTMetaData(TdsTypeInfo metaData, TdsParser
}
if (byteLength != 0)
{
result = stateObj.TryReadString(byteLength, out metaData.Udt.SchemaName);
result = stateObj.TryReadString(byteLength, out metaData.UdtTypeInfo.SchemaName);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -5827,7 +5827,7 @@ private TdsOperationStatus TryProcessUDTMetaData(TdsTypeInfo metaData, TdsParser
}
if (byteLength != 0)
{
result = stateObj.TryReadString(byteLength, out metaData.Udt.TypeName);
result = stateObj.TryReadString(byteLength, out metaData.UdtTypeInfo.TypeName);
if (result != TdsOperationStatus.Done)
{
return result;
Expand All @@ -5841,7 +5841,7 @@ private TdsOperationStatus TryProcessUDTMetaData(TdsTypeInfo metaData, TdsParser
}
if (shortLength != 0)
{
result = stateObj.TryReadString(shortLength, out metaData.Udt.AssemblyQualifiedName);
result = stateObj.TryReadString(shortLength, out metaData.UdtTypeInfo.AssemblyQualifiedName);
if (result != TdsOperationStatus.Done)
{
return result;
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Microsoft.Data.SqlClient.Parser.Tokens;
/// Represents metadata information for a specific column in a TDS stream. Corresponds with a
/// single column within a SQLCOLMETADATA/SQLALTMETADATA token.
/// </summary>
// @TODO: We have a mix of patterns here where some subtypes are contained within the types, while some are inherited. It seems this class would be better suited to contain the TdsTypeInfo rather than inherit from it.
internal sealed class TdsColumnMetadata : TdsTypeInfo
{
[Flags]
Expand Down Expand Up @@ -70,16 +71,29 @@ internal TdsColumnMetadata(int ordinal) : base()
Ordinal = ordinal;
}

private TdsColumnMetadata(TdsColumnMetadata original) : base(original)
{
_flags = original._flags;

baseColumn = original.baseColumn;
column = original.column;
tableName = original.tableName;
tableNum = original.tableNum;
op = original.op;
Operand = original.Operand;
Ordinal = original.Ordinal;
}

/// <summary>
/// Gets the catalog name associated with the column's metadata.
/// </summary>
internal string CatalogName => tableName.CatalogName;


internal bool Is2008DateTimeType => DbType is SqlDbType.Date
or SqlDbType.Time
or SqlDbType.DateTime2
or SqlDbType.DateTimeOffset;
or SqlDbType.Time
or SqlDbType.DateTime2
or SqlDbType.DateTimeOffset;

/// <summary>
/// Indicates whether the column is part of a sparse column set.
Expand Down Expand Up @@ -187,19 +201,8 @@ public byte Updatability
/// <returns>
/// A new TdsColumnMetadata object that is a copy of the current instance.
/// </returns>
public object Clone()
{
TdsColumnMetadata result = new TdsColumnMetadata(Ordinal);
result.CopyFrom(this);
result.column = column;
result.baseColumn = baseColumn;
result.tableName = tableName;
result.tableNum = tableNum;
result._flags = _flags;
result.op = op;
result.Operand = Operand;
return result;
}
internal TdsColumnMetadata Clone() =>
new TdsColumnMetadata(this);

private bool HasFlag(MetadataFlags flag)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private TdsColumnMetadataToken(TdsColumnMetadataToken original)
_metadataArray = new TdsColumnMetadata[original._metadataArray.Length];
for (int idx = 0; idx < _metadataArray.Length; idx++)
{
_metadataArray[idx] = (TdsColumnMetadata)original._metadataArray[idx].Clone();
_metadataArray[idx] = original._metadataArray[idx].Clone();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,30 @@ internal TdsTypeInfo()
{
}

protected TdsTypeInfo(TdsTypeInfo original)
{
// @TODO: Some of these fields are not simple types, should they also be cloned?

collation = original.collation;
flags = original.flags;
length = original.length;
precision = original.precision;
scale = original.scale;

CodePage = original.CodePage;
DbType = original.DbType;
Encoding = original.Encoding;
MetaType = original.MetaType; // This is a cached instance, it should not be cloned.
TdsType = original.TdsType;

UdtTypeInfo = original.UdtTypeInfo?.Clone();
XmlTypeInfo = original.XmlTypeInfo?.Clone();

BaseTypeInfo = original.BaseTypeInfo;
CipherMetadata = original.CipherMetadata;
IsEncrypted = original.IsEncrypted;
}

/// <summary>
/// Gets or sets the plaintext type information for the column if the column is encrypted.
/// </summary>
Expand Down Expand Up @@ -130,43 +154,12 @@ public bool IsNullable
/// <summary>
/// Gets or sets the UDT metadata associated with this object.
/// </summary>
public SqlMetaDataUdt Udt { get; set; }
public TdsUdtTypeInfo UdtTypeInfo { get; set; }

/// <summary>
/// Gets or sets the metadata for the XML schema collection associated with this data type.
/// </summary>
public SqlMetaDataXmlSchemaCollection XmlSchemaCollection { get; set; }

// @TODO: Can this be converted to Clone like all the other token types do?
internal virtual void CopyFrom(TdsTypeInfo original)
{
this.DbType = original.DbType;
this.TdsType = original.TdsType;
this.precision = original.precision;
this.scale = original.scale;
this.length = original.length;
this.collation = original.collation;
this.CodePage = original.CodePage;
this.Encoding = original.Encoding;
this.MetaType = original.MetaType;
this.flags = original.flags;

if (original.Udt != null)
{
Udt = new SqlMetaDataUdt();
Udt.CopyFrom(original.Udt);
}

if (original.XmlSchemaCollection != null)
{
XmlSchemaCollection = new SqlMetaDataXmlSchemaCollection();
XmlSchemaCollection.CopyFrom(original.XmlSchemaCollection);
}

this.IsEncrypted = original.IsEncrypted;
this.BaseTypeInfo = original.BaseTypeInfo;
this.CipherMetadata = original.CipherMetadata;
}
public TdsXmlTypeInfo XmlTypeInfo { get; set; }

private bool HasFlag(TdsTypeInfoFlags flag)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Data.SqlClient.Parser.Tokens;

/// <summary>
/// Represents UDT metadata inside a TYPE_INFO TDS object used by metadata and return value tokens.
/// </summary>
internal sealed class TdsUdtTypeInfo
{
/// <summary>
/// Represents the fully qualified type name of the UDT, including the name of the assembly
/// in which the type is defined.
/// </summary>
// @TODO: This cannot be an auto property yet because this value is set via an out parameter in TryRead*.
internal string AssemblyQualifiedName;

/// <summary>
/// Represents the name of the database associated with the UDT.
/// </summary>
// @TODO: This cannot be an auto property yet because this value is set via an out parameter in TryRead*.
internal string DatabaseName;

/// <summary>
/// Represents the schema name of the UDT within the TYPE_INFO TDS object.
/// </summary>
// @TODO: This cannot be an auto property yet because this value is set via an out parameter in TryRead*.
internal string SchemaName;

/// <summary>
/// Represents the name of the UDT as specified in the TYPE_INFO TDS object.
/// </summary>
// @TODO: This cannot be an auto property yet because this value is set via an out parameter in TryRead*.
internal string TypeName;

/// <summary>
/// Represents the data type of the UDT, providing metadata necessary for runtime type resolution
/// and compatibility checks.
/// </summary>
#if NET
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
#endif
internal Type Type { get; set; }

/// <summary>
/// Creates a new instance of <see cref="TdsUdtTypeInfo"/> and initializes it with the values
/// of the current instance.
/// </summary>
internal TdsUdtTypeInfo Clone()
{
return new TdsUdtTypeInfo
{
AssemblyQualifiedName = AssemblyQualifiedName,
DatabaseName = DatabaseName,
SchemaName = SchemaName,
Type = Type,
TypeName = TypeName
};
}
}
Loading
Loading