-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
runtime/src/libraries/Common/src/System/Data/ProviderBase/DbMetaDataFactory.cs
Lines 225 to 314 in 6072e4d
| internal DataRow FindMetaDataCollectionRow(string collectionName) | |
| { | |
| bool versionFailure; | |
| bool haveExactMatch; | |
| bool haveMultipleInexactMatches; | |
| string candidateCollectionName; | |
| DataTable metaDataCollectionsTable = _metaDataCollectionsDataSet.Tables[DbMetaDataCollectionNames.MetaDataCollections]; | |
| if (metaDataCollectionsTable == null) | |
| { | |
| throw ADP.InvalidXml(); | |
| } | |
| DataColumn collectionNameColumn = metaDataCollectionsTable.Columns[DbMetaDataColumnNames.CollectionName]; | |
| if ((null == collectionNameColumn) || (typeof(string) != collectionNameColumn.DataType)) | |
| { | |
| throw ADP.InvalidXmlMissingColumn(DbMetaDataCollectionNames.MetaDataCollections, DbMetaDataColumnNames.CollectionName); | |
| } | |
| DataRow requestedCollectionRow = null; | |
| string exactCollectionName = null; | |
| // find the requested collection | |
| versionFailure = false; | |
| haveExactMatch = false; | |
| haveMultipleInexactMatches = false; | |
| foreach (DataRow row in metaDataCollectionsTable.Rows) | |
| { | |
| candidateCollectionName = row[collectionNameColumn, DataRowVersion.Current] as string; | |
| if (string.IsNullOrEmpty(candidateCollectionName)) | |
| { | |
| throw ADP.InvalidXmlInvalidValue(DbMetaDataCollectionNames.MetaDataCollections, DbMetaDataColumnNames.CollectionName); | |
| } | |
| if (ADP.CompareInsensitiveInvariant(candidateCollectionName, collectionName)) | |
| { | |
| if (SupportedByCurrentVersion(row) == false) | |
| { | |
| versionFailure = true; | |
| } | |
| else | |
| { | |
| if (collectionName == candidateCollectionName) | |
| { | |
| if (haveExactMatch == true) | |
| { | |
| throw ADP.CollectionNameIsNotUnique(collectionName); | |
| } | |
| requestedCollectionRow = row; | |
| exactCollectionName = candidateCollectionName; | |
| haveExactMatch = true; | |
| } | |
| else | |
| { | |
| // have an inexact match - ok only if it is the only one | |
| if (exactCollectionName != null) | |
| { | |
| // can't fail here becasue we may still find an exact match | |
| haveMultipleInexactMatches = true; | |
| } | |
| requestedCollectionRow = row; | |
| exactCollectionName = candidateCollectionName; | |
| } | |
| } | |
| } | |
| } | |
| if (requestedCollectionRow == null) | |
| { | |
| if (versionFailure == false) | |
| { | |
| throw ADP.UndefinedCollection(collectionName); | |
| } | |
| else | |
| { | |
| throw ADP.UnsupportedVersion(collectionName); | |
| } | |
| } | |
| if ((haveExactMatch == false) && (haveMultipleInexactMatches == true)) | |
| { | |
| throw ADP.AmbigousCollectionName(collectionName); | |
| } | |
| return requestedCollectionRow; | |
| } |
Seems the code here want to do an case-sensitive match first, and fallback to an case-insensitive match, and throw if get more than one matches(in case-sensitive or case-insensitive).
But if it first hit an case-sensitive match, and then some case-insensitive match, var requestedCollectionRow will be overwrite by the last case-insensitive match, but won't throw AmbigousCollectionName since haveExactMatch is true, and finally return the case-insensitive result instead of the extra match one.
| else |
Is it the expected logic? Maybe it should be
else if (!haveExactMatch) here instead?
Regression?
No. And didn't hit any problem with this, just found this when do some research for the behavior of DbConnection.GetScmema().
Other information
Note: There is also some copy of this file in OleDb and MD.SqlClient, which have the same problem.
https://github.com/dotnet/runtime/search?q=FindMetaDataCollectionRow&unscoped_q=FindMetaDataCollectionRow
https://github.com/dotnet/sqlclient/search?q=FindMetaDataCollectionRow&unscoped_q=FindMetaDataCollectionRow