address feedback
authorWraith2 <wraith2@gmail.com>
Wed, 20 Mar 2019 19:49:19 +0000 (19:49 +0000)
committerWraith2 <wraith2@gmail.com>
Wed, 20 Mar 2019 19:49:19 +0000 (19:49 +0000)
Commit migrated from https://github.com/dotnet/corefx/commit/a15c35040c6bdcf8a7e762ed5071ad2a19be426b

src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommand.cs
src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlParameter.cs
src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/UdtTest/UdtTest2.cs

index b09a0b4..a5cc962 100644 (file)
@@ -3332,18 +3332,15 @@ namespace System.Data.SqlClient
                         if (parameter.IsDerivedParameterTypeName)
                         {
                             string[] parts = MultipartIdentifier.ParseMultipartIdentifier(parameter.TypeName, "[\"", "]\"", SR.SQL_TDSParserTableName, false);
-                            if (parts != null)
+                            if (parts != null && parts.Length==4) // will always return int[4] right justified
                             {
-                                int length = parts.Length;
                                 if (
-                                    length >= 3 && //require at least 3 parts
-                                    parts[length - 1] != null && // name must not be null
-                                    parts[length - 2] != null && // schema must not be null
-                                    parts[length - 3] != null && // server should not be null or we don't need to remove it
-                                    (length == 3 || parts[length - 4] == null) // if a database space is availble then is must be null
+                                    parts[3] != null && // name must not be null
+                                    parts[2] != null && // schema must not be null
+                                    parts[1] != null // server should not be null or we don't need to remove it
                                 )
                                 {
-                                    parameter.TypeName = QuoteIdentifier(parts.AsSpan(length-2));
+                                    parameter.TypeName = QuoteIdentifier(parts.AsSpan(2,2));
                                 }
                             }
                         }
index 02aeb31..d2d8fa5 100644 (file)
@@ -85,7 +85,7 @@ namespace System.Data.SqlClient
             CoercedValueIsDataFeed = 1 << 5,
             IsDerivedParameterTypeName = 1 << 6,
             SourceColumnNullMapping = 1 << 7,
-            HasScale = 1 << 9,  // V1.0 compat, ignore _hasScale
+            HasScale = 1 << 8,  // V1.0 compat, ignore _hasScale
         }
 
         private MetaType _metaType;
index 389f952..cd9392c 100644 (file)
@@ -343,7 +343,7 @@ namespace System.Data.SqlClient.ManualTesting.Tests
         }
 
         [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
-        public void UDTParams_DeriveParameters()
+        public void UDTParams_DeriveParameters_CheckAutoFixSuccess()
         {
             // the type and sproc must be commited to the database or this test will deadlock with a schema lock violation
             // if you are missing these database entities then you should look for an updated version of the database creation script
@@ -403,6 +403,68 @@ namespace System.Data.SqlClient.ManualTesting.Tests
         }
 
         [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
+        public void UDTParams_DeriveParameters_CheckAutoFixOverride()
+        {
+            // the type and sproc must be commited to the database or this test will deadlock with a schema lock violation
+            // if you are missing these database entities then you should look for an updated version of the database creation script
+
+            string sprocName = "sp_insert_customers";
+            string typeName = "CustomerAddress";
+            string customerAddressTypeIncorrectName = $"{DataTestUtility.UdtTestDbName}.dbo.{typeName.Trim('[', ']')}";
+            string customerAddressTypeCorrectedName = $"[dbo].[{typeName.Trim('[', ']')}]";
+            string customerParameterName = "@customers";
+
+            Address addr = Address.Parse("123 baker st || Redmond");
+            DataTable table = new DataTable();
+            table.Columns.Add();
+            table.Columns.Add();
+            table.Rows.Add("john", addr);
+
+            using (SqlConnection connection = new SqlConnection(_connStr))
+            {
+                connection.Open();
+                using (SqlTransaction transaction = connection.BeginTransaction())
+                using (SqlCommand cmd = new SqlCommand(sprocName, connection, transaction))
+                {
+                    try
+                    {
+                        cmd.CommandType = CommandType.StoredProcedure;
+
+                        SqlCommandBuilder.DeriveParameters(cmd);
+
+                        Assert.NotNull(cmd.Parameters);
+                        Assert.Equal(2, cmd.Parameters.Count); // [return_value, table]
+
+                        SqlParameter p = cmd.Parameters[1];
+
+                        Assert.Equal(customerParameterName, p.ParameterName);
+                        Assert.Equal(SqlDbType.Structured, p.SqlDbType);
+                        Assert.Equal(customerAddressTypeIncorrectName, p.TypeName); // the 3 part name is incorrect but needs to be maintained for compatibility
+                        p.Value = table;
+
+                        p.TypeName = customerAddressTypeIncorrectName; // force using the incorrect name by manually setting it
+
+                        Assert.Throws<SqlException>(
+                            () => cmd.ExecuteNonQuery()
+                        );
+                    }
+                    finally
+                    {
+                        try
+                        {
+                            transaction.Rollback();
+                        }
+                        catch
+                        {
+                            // ignore rollback failure exceptions to preserve original thrown error in test result
+                        }
+                    }
+                }
+
+            }
+        }
+
+        [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsUdtTestDatabasePresent), nameof(DataTestUtility.AreConnStringsSetup))]
         public void Reader_PointEarly()
         {
             using (SqlConnection conn = new SqlConnection(_connStr))