diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml index e013016ee9..01d30ee8d3 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml @@ -60,5 +60,9 @@ A constant for use with the **GetSchema** method that represents the **ColumnSetColumns** collection. To be added. + + A constant for use with the **GetSchema** method that represents the **StructuredTypeMembers** collection. + To be added. + diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index af9532a1ae..73ddc2f575 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -197,7 +197,7 @@ 4 4 SQLCommand - SELECT DB_NAME() AS TYPE_CATALOG, sc.name AS TYPE_SCHEMA, tt.name AS TYPE_NAME, c.name AS MEMBER_NAME, ColumnProperty(c.object_id, c.name, 'ordinal') AS ORDINAL_POSITION, convert(nvarchar(4000), object_definition(c.default_object_id)) AS MEMBER_DEFAULT, convert(varchar(3), CASE c.is_nullable WHEN 1 THEN 'YES' ELSE 'NO' END) AS IS_NULLABLE, type_name(c.system_type_id) AS DATA_TYPE, ColumnProperty(c.object_id, c.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH, ColumnProperty(c.object_id, c.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH, convert(tinyint, CASE /* int/decimal/numeric/real/float/money */ WHEN c.system_type_id IN (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN c.precision END) AS NUMERIC_PRECISION, convert(smallint, CASE /* int/money/decimal/numeric */ WHEN c.system_type_id IN (48, 52, 56, 60, 106, 108, 122, 127) THEN 10 WHEN c.system_type_id IN (59, 62) THEN 2 END) AS NUMERIC_PRECISION_RADIX, /* real/float */ convert(int, CASE /* datetime/smalldatetime */ WHEN c.system_type_id IN (58, 61) THEN NULL ELSE odbcscale(c.system_type_id, c.scale) END) AS NUMERIC_SCALE, convert(smallint, CASE /* datetime/smalldatetime */ WHEN c.system_type_id IN (58, 61) THEN 3 END) AS DATETIME_PRECISION, convert(sysname, null) AS CHARACTER_SET_CATALOG, convert(sysname, null) AS CHARACTER_SET_SCHEMA, convert(sysname, CASE WHEN c.system_type_id IN (35, 167, 175) /*char/varchar/text*/ THEN CollationProperty(c.collation_name, 'sqlcharsetname') WHEN c.system_type_id IN (99, 231, 239) /*nchar/nvarchar/ntext*/ THEN N'UNICODE' END) AS CHARACTER_SET_NAME, convert(sysname, null) AS COLLATION_CATALOG FROM sys.schemas sc join sys.objects o on sc.schema_id = o.schema_id JOIN sys.table_types tt on o.object_id = tt.type_table_object_id JOIN sys.columns c ON c.object_id = o.object_id LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE o.type IN ('TT') AND (DB_NAME() = @Catalog or (@Catalog is null)) and (sc.name = @Owner or (@Owner is null)) and (tt.name = @Type or (@Type is null)) and (c.name = @Member or (@Member is null)) order by sc.name, tt.name, c.name + SELECT DB_NAME() AS TYPE_CATALOG, sc.name AS TYPE_SCHEMA, tt.name AS TYPE_NAME, c.name AS MEMBER_NAME, ColumnProperty(c.object_id, c.name, 'ordinal') AS ORDINAL_POSITION, convert(nvarchar(4000), object_definition(c.default_object_id)) AS MEMBER_DEFAULT, convert(varchar(3), CASE c.is_nullable WHEN 1 THEN 'YES' ELSE 'NO' END) AS IS_NULLABLE, type_name(c.system_type_id) AS DATA_TYPE, ColumnProperty(c.object_id, c.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH, ColumnProperty(c.object_id, c.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH, convert(tinyint, CASE WHEN c.system_type_id IN /* int/decimal/numeric/real/float/money */ (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN c.precision END) AS NUMERIC_PRECISION, convert(smallint, CASE WHEN c.system_type_id IN /* int/money/decimal/numeric */ (48, 52, 56, 60, 106, 108, 122, 127) THEN 10 WHEN c.system_type_id IN /* real/float */ (59, 62) THEN 2 END) AS NUMERIC_PRECISION_RADIX, convert(int, CASE WHEN c.system_type_id IN /* datetime/smalldatetime */ (58, 61) THEN NULL ELSE odbcscale(c.system_type_id, c.scale) END) AS NUMERIC_SCALE, convert(smallint, CASE WHEN c.system_type_id IN /* datetime/smalldatetime */ (58, 61) THEN 3 END) AS DATETIME_PRECISION, convert(sysname, null) AS CHARACTER_SET_CATALOG, convert(sysname, null) AS CHARACTER_SET_SCHEMA, convert(sysname, CASE WHEN c.system_type_id IN /* char/varchar/text */ (35, 167, 175) THEN CollationProperty(c.collation_name, 'sqlcharsetname') WHEN c.system_type_id IN /* nchar/nvarchar/ntext */ (99, 231, 239) THEN N'UNICODE' END) AS CHARACTER_SET_NAME, convert(sysname, null) AS COLLATION_CATALOG FROM sys.table_types tt join sys.objects o on o.object_id = tt.type_table_object_id JOIN sys.schemas sc on sc.schema_id = tt.schema_id JOIN sys.columns c ON c.object_id = o.object_id LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE o.type IN ('TT') AND (DB_NAME() = @Catalog or (@Catalog is null)) and (sc.name = @Owner or (@Owner is null)) and (tt.name = @Type or (@Type is null)) and (c.name = @Member or (@Member is null)) order by sc.name, tt.name, c.name 09.00.000.0 diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index af9532a1ae..73ddc2f575 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -197,7 +197,7 @@ 4 4 SQLCommand - SELECT DB_NAME() AS TYPE_CATALOG, sc.name AS TYPE_SCHEMA, tt.name AS TYPE_NAME, c.name AS MEMBER_NAME, ColumnProperty(c.object_id, c.name, 'ordinal') AS ORDINAL_POSITION, convert(nvarchar(4000), object_definition(c.default_object_id)) AS MEMBER_DEFAULT, convert(varchar(3), CASE c.is_nullable WHEN 1 THEN 'YES' ELSE 'NO' END) AS IS_NULLABLE, type_name(c.system_type_id) AS DATA_TYPE, ColumnProperty(c.object_id, c.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH, ColumnProperty(c.object_id, c.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH, convert(tinyint, CASE /* int/decimal/numeric/real/float/money */ WHEN c.system_type_id IN (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN c.precision END) AS NUMERIC_PRECISION, convert(smallint, CASE /* int/money/decimal/numeric */ WHEN c.system_type_id IN (48, 52, 56, 60, 106, 108, 122, 127) THEN 10 WHEN c.system_type_id IN (59, 62) THEN 2 END) AS NUMERIC_PRECISION_RADIX, /* real/float */ convert(int, CASE /* datetime/smalldatetime */ WHEN c.system_type_id IN (58, 61) THEN NULL ELSE odbcscale(c.system_type_id, c.scale) END) AS NUMERIC_SCALE, convert(smallint, CASE /* datetime/smalldatetime */ WHEN c.system_type_id IN (58, 61) THEN 3 END) AS DATETIME_PRECISION, convert(sysname, null) AS CHARACTER_SET_CATALOG, convert(sysname, null) AS CHARACTER_SET_SCHEMA, convert(sysname, CASE WHEN c.system_type_id IN (35, 167, 175) /*char/varchar/text*/ THEN CollationProperty(c.collation_name, 'sqlcharsetname') WHEN c.system_type_id IN (99, 231, 239) /*nchar/nvarchar/ntext*/ THEN N'UNICODE' END) AS CHARACTER_SET_NAME, convert(sysname, null) AS COLLATION_CATALOG FROM sys.schemas sc join sys.objects o on sc.schema_id = o.schema_id JOIN sys.table_types tt on o.object_id = tt.type_table_object_id JOIN sys.columns c ON c.object_id = o.object_id LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE o.type IN ('TT') AND (DB_NAME() = @Catalog or (@Catalog is null)) and (sc.name = @Owner or (@Owner is null)) and (tt.name = @Type or (@Type is null)) and (c.name = @Member or (@Member is null)) order by sc.name, tt.name, c.name + SELECT DB_NAME() AS TYPE_CATALOG, sc.name AS TYPE_SCHEMA, tt.name AS TYPE_NAME, c.name AS MEMBER_NAME, ColumnProperty(c.object_id, c.name, 'ordinal') AS ORDINAL_POSITION, convert(nvarchar(4000), object_definition(c.default_object_id)) AS MEMBER_DEFAULT, convert(varchar(3), CASE c.is_nullable WHEN 1 THEN 'YES' ELSE 'NO' END) AS IS_NULLABLE, type_name(c.system_type_id) AS DATA_TYPE, ColumnProperty(c.object_id, c.name, 'charmaxlen') AS CHARACTER_MAXIMUM_LENGTH, ColumnProperty(c.object_id, c.name, 'octetmaxlen') AS CHARACTER_OCTET_LENGTH, convert(tinyint, CASE WHEN c.system_type_id IN /* int/decimal/numeric/real/float/money */ (48, 52, 56, 59, 60, 62, 106, 108, 122, 127) THEN c.precision END) AS NUMERIC_PRECISION, convert(smallint, CASE WHEN c.system_type_id IN /* int/money/decimal/numeric */ (48, 52, 56, 60, 106, 108, 122, 127) THEN 10 WHEN c.system_type_id IN /* real/float */ (59, 62) THEN 2 END) AS NUMERIC_PRECISION_RADIX, convert(int, CASE WHEN c.system_type_id IN /* datetime/smalldatetime */ (58, 61) THEN NULL ELSE odbcscale(c.system_type_id, c.scale) END) AS NUMERIC_SCALE, convert(smallint, CASE WHEN c.system_type_id IN /* datetime/smalldatetime */ (58, 61) THEN 3 END) AS DATETIME_PRECISION, convert(sysname, null) AS CHARACTER_SET_CATALOG, convert(sysname, null) AS CHARACTER_SET_SCHEMA, convert(sysname, CASE WHEN c.system_type_id IN /* char/varchar/text */ (35, 167, 175) THEN CollationProperty(c.collation_name, 'sqlcharsetname') WHEN c.system_type_id IN /* nchar/nvarchar/ntext */ (99, 231, 239) THEN N'UNICODE' END) AS CHARACTER_SET_NAME, convert(sysname, null) AS COLLATION_CATALOG FROM sys.table_types tt join sys.objects o on o.object_id = tt.type_table_object_id JOIN sys.schemas sc on sc.schema_id = tt.schema_id JOIN sys.columns c ON c.object_id = o.object_id LEFT JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE o.type IN ('TT') AND (DB_NAME() = @Catalog or (@Catalog is null)) and (sc.name = @Owner or (@Owner is null)) and (tt.name = @Type or (@Type is null)) and (c.name = @Member or (@Member is null)) order by sc.name, tt.name, c.name 09.00.000.0 diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientMetaDataCollectionNames.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientMetaDataCollectionNames.cs index 04ac2aab0f..d67d58d18d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientMetaDataCollectionNames.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientMetaDataCollectionNames.cs @@ -48,5 +48,9 @@ public static class SqlClientMetaDataCollectionNames /// public static readonly string ColumnSetColumns = "ColumnSetColumns"; + + /// + public static readonly string StructuredTypeMembers = "StructuredTypeMembers"; + } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientMetaDataCollectionNamesTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientMetaDataCollectionNamesTest.cs index 789949ee68..7c51a326c2 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientMetaDataCollectionNamesTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlClientMetaDataCollectionNamesTest.cs @@ -25,6 +25,7 @@ public void ValuesTest() Assert.Equal("Views", SqlClientMetaDataCollectionNames.Views); Assert.Equal("AllColumns", SqlClientMetaDataCollectionNames.AllColumns); Assert.Equal("ColumnSetColumns", SqlClientMetaDataCollectionNames.ColumnSetColumns); + Assert.Equal("StructuredTypeMembers", SqlClientMetaDataCollectionNames.StructuredTypeMembers); } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs index 7b2742e8d6..283ddc5c63 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs @@ -64,7 +64,7 @@ public static void GetAllColumnsFromSchema() { VerifySchemaTable(SqlClientMetaDataCollectionNames.AllColumns, new string[] { "IS_NULLABLE", "COLUMN_DEFAULT", "IS_FILESTREAM", "IS_SPARSE", "IS_COLUMN_SET" }); } - + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void GetColumnSetColumnsFromSchema() { @@ -93,7 +93,13 @@ public static void GetViewColumnsFromSchema() public static void GetUserDefinedTypesFromSchema() { VerifySchemaTable(SqlClientMetaDataCollectionNames.UserDefinedTypes, new string[] { "assembly_name", "version_revision", "culture_info" }); - } + } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + public static void GetStructuredTypeMembersFromSchema() + { + VerifySchemaTable(SqlClientMetaDataCollectionNames.StructuredTypeMembers, new string[] { "TYPE_CATALOG", "TYPE_SCHEMA", "TYPE_NAME", "MEMBER_NAME", "ORDINAL_POSITION" }); + } private static void VerifySchemaTable(string schemaItemName, string[] testColumnNames) { @@ -104,11 +110,11 @@ private static void VerifySchemaTable(string schemaItemName, string[] testColumn using (SqlConnection connection = new SqlConnection(builder.ConnectionString)) { - // Connect to the database then retrieve the schema information. + // Connect to the database then retrieve the schema information connection.Open(); DataTable table = connection.GetSchema(schemaItemName); - // Get all table columns + // Get all table columns HashSet columnNames = new HashSet(); foreach (DataColumn column in table.Columns)