Skip to content

Commit 32fd87d

Browse files
Fix #1418 - Column.GetAlias should account for other suffixes
1 parent a37e65e commit 32fd87d

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

src/NHibernate.Test/MappingTest/ColumnFixture.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public void StringSqlType()
4040
Assert.AreEqual("NVARCHAR(100)", column.GetSqlType(_dialect, null));
4141
}
4242

43+
// Should be kept synchronized with Column same constant.
44+
private const int _charactersLeftCount = 4;
4345

4446
[TestCase("xxxxyyyyz")]
4547
[TestCase("xxxxyyyyzz")]
@@ -60,7 +62,7 @@ public void GetAliasRespectsMaxAliasLength(string columnName)
6062
var column = new Column(columnName);
6163
string generatedAlias = column.GetAlias(dialect);
6264

63-
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength));
65+
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength - _charactersLeftCount));
6466
}
6567

6668
[TestCase("xxxxyyyyz")]
@@ -84,7 +86,7 @@ public void GetAliasWithTableSuffixRespectsMaxAliasLength(string columnName)
8486

8587
string generatedAlias = column.GetAlias(dialect, table);
8688

87-
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength));
89+
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength - _charactersLeftCount));
8890
}
8991

9092
private static string AdjustColumnNameToMaxLength(string columnName, GenericDialect dialect, int referenceMaxLength)

src/NHibernate/Mapping/Column.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,14 @@ public string GetQuotedName(Dialect.Dialect d)
115115
return IsQuoted ? d.QuoteForColumnName(_name) : _name;
116116
}
117117

118+
// Accomodate the one character suffix appended in AbstractCollectionPersister and
119+
// the SelectFragment suffix up to 99 joins.
120+
private const int _charactersLeftCount = 4;
118121

119122
/// <summary>
120123
/// For any column name, generate an alias that is unique to that
121124
/// column name, and also take Dialect.MaxAliasLength into account.
125+
/// It keeps four characters left for accommodating additional suffixes.
122126
/// </summary>
123127
public string GetAlias(Dialect.Dialect dialect)
124128
{
@@ -127,6 +131,7 @@ public string GetAlias(Dialect.Dialect dialect)
127131

128132
private string GetAlias(int maxAliasLength)
129133
{
134+
var usableLength = maxAliasLength - _charactersLeftCount;
130135
var name = CanonicalName;
131136
string alias = name;
132137
string suffix = UniqueInteger.ToString() + StringHelper.Underscore;
@@ -148,25 +153,27 @@ private string GetAlias(int maxAliasLength)
148153
// reason, the checks for "_quoted" and "rowid" looks redundant. If you remove
149154
// those checks, then the double checks for total length can be reduced to one.
150155
// But I will leave it like this for now to make it look similar. /Oskar 2016-08-20
151-
bool useRawName = name.Length + suffix.Length <= maxAliasLength &&
156+
bool useRawName = name.Length + suffix.Length <= usableLength &&
152157
!_quoted &&
153158
!StringHelper.EqualsCaseInsensitive(name, "rowid");
154159
if (!useRawName)
155160
{
156-
if (suffix.Length >= maxAliasLength)
161+
if (suffix.Length >= usableLength)
157162
{
158163
throw new MappingException(
159-
string.Format(
160-
"Unique suffix {0} length must be less than maximum {1} characters.",
161-
suffix,
162-
maxAliasLength));
164+
$"Unique suffix {suffix} length must be less than maximum {usableLength} characters.");
163165
}
164-
if (alias.Length + suffix.Length > maxAliasLength)
165-
alias = alias.Substring(0, maxAliasLength - suffix.Length);
166+
if (alias.Length + suffix.Length > usableLength)
167+
alias = alias.Substring(0, usableLength - suffix.Length);
166168
}
167169
return alias + suffix;
168170
}
169171

172+
/// <summary>
173+
/// For any column name, generate an alias that is unique to that
174+
/// column name and table, and also take Dialect.MaxAliasLength into account.
175+
/// It keeps four characters left for accommodating additional suffixes.
176+
/// </summary>
170177
public string GetAlias(Dialect.Dialect dialect, Table table)
171178
{
172179
string suffix = table.UniqueInteger.ToString() + StringHelper.Underscore;

src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,11 @@ public AbstractCollectionPersister(Mapping.Collection collection, ICacheConcurre
248248
foreach (Column col in collection.Owner.Key.ColumnIterator)
249249
{
250250
keyColumnNames[k] = col.GetQuotedName(dialect);
251-
keyColumnAliases[k] = col.GetAlias(dialect) + "_owner_"; // Force the alias to be unique in case it conflicts with an alias in the entity
251+
// Force the alias to be unique in case it conflicts with an alias in the entity
252+
// As per Column.GetAlias, we have 3 characters left for SelectFragment suffix and one for here.
253+
// Since suffixes are composed of digits and '_', and GetAlias is already suffixed, adding any other
254+
// letter will avoid collision.
255+
keyColumnAliases[k] = col.GetAlias(dialect) + "o";
252256
k++;
253257
}
254258
joinColumnNames = new string[collection.Key.ColumnSpan];

0 commit comments

Comments
 (0)