Skip to content

Commit fad699d

Browse files
authored
Merge pull request #503 from oskarb/NH-3899
Nh 3899 Fixes to avoid too long column aliases
2 parents 3d6305e + 16fafd1 commit fad699d

File tree

2 files changed

+85
-21
lines changed

2 files changed

+85
-21
lines changed

src/NHibernate.Test/MappingTest/ColumnFixture.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,53 @@ public void StringSqlType()
3939
column.Length = 100;
4040
Assert.AreEqual("NVARCHAR(100)", column.GetSqlType(_dialect, null));
4141
}
42+
43+
44+
[TestCase("xxxxyyyyz")]
45+
[TestCase("xxxxyyyyzz")]
46+
[TestCase("xxxxyyyyzzz")]
47+
[TestCase("xxxxyyy4z", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
48+
[TestCase("xxxxyyyz4z", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
49+
[TestCase("xxxxyyyzz4z", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
50+
[TestCase("xxxxyyyy4", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
51+
[TestCase("xxxxyyyyz4", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
52+
[TestCase("xxxxyyyyzz4", Description = "Non-letter digit character would be cut, make sure we don't skip length check.")]
53+
public void GetAliasRespectsMaxAliasLength(string columnName)
54+
{
55+
var dialect = new GenericDialect();
56+
57+
// Verify test case assumption.
58+
Assert.That(dialect.MaxAliasLength, Is.EqualTo(10));
59+
60+
var column = new Column(columnName);
61+
string generatedAlias = column.GetAlias(dialect);
62+
63+
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength));
64+
}
65+
66+
67+
[TestCase("xxxxyyyyz")]
68+
[TestCase("xxxxyyyyzz")]
69+
[TestCase("xxxxyyyyzzz")]
70+
[TestCase("xxxxyyy4z")]
71+
[TestCase("xxxxyyyz4z")]
72+
[TestCase("xxxxyyyzz4z")]
73+
[TestCase("xxxxyyyy4")]
74+
[TestCase("xxxxyyyyz4")]
75+
[TestCase("xxxxyyyyzz4")]
76+
public void GetAliasWithTableSuffixRespectsMaxAliasLength(string columnName)
77+
{
78+
var dialect = new GenericDialect();
79+
80+
// Verify test case assumption.
81+
Assert.That(dialect.MaxAliasLength, Is.EqualTo(10));
82+
83+
var table = new Table();
84+
var column = new Column(columnName);
85+
86+
string generatedAlias = column.GetAlias(dialect, table);
87+
88+
Assert.That(generatedAlias, Has.Length.LessThanOrEqualTo(dialect.MaxAliasLength));
89+
}
4290
}
43-
}
91+
}

src/NHibernate/Mapping/Column.cs

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

118-
/**
119-
* For any column name, generate an alias that is unique
120-
* to that column name, and also 10 characters or less
121-
* in length.
122-
*/
123118

119+
/// <summary>
120+
/// For any column name, generate an alias that is unique to that
121+
/// column name, and also take Dialect.MaxAliasLength into account.
122+
/// </summary>
124123
public string GetAlias(Dialect.Dialect dialect)
124+
{
125+
return GetAlias(dialect.MaxAliasLength);
126+
}
127+
128+
private string GetAlias(int maxAliasLength)
125129
{
126130
string alias = _name;
127-
string suffix = UniqueInteger.ToString() + '_';
131+
string suffix = UniqueInteger.ToString() + StringHelper.Underscore;
132+
128133
int lastLetter = StringHelper.LastIndexOfLetter(_name);
129134
if (lastLetter == -1)
130135
{
@@ -134,27 +139,38 @@ public string GetAlias(Dialect.Dialect dialect)
134139
{
135140
alias = _name.Substring(0, lastLetter + 1);
136141
}
137-
if (alias.Length > dialect.MaxAliasLength)
138-
{
139-
alias = alias.Substring(0, dialect.MaxAliasLength - suffix.Length);
140-
}
141-
bool useRawName = _name.Equals(alias) &&
142-
!_quoted &&
143-
!StringHelper.EqualsCaseInsensitive(_name, "rowid");
144142

145-
if (useRawName)
146-
{
147-
return alias;
148-
}
149-
else
143+
// Updated logic ported from Hibernate's fix for HHH-8073.
144+
// https://github.com/hibernate/hibernate-orm/commit/79073a98f0e4ed225fe4608b67594196f86d48d7
145+
// To my mind it is weird - since the suffix is now always used, it
146+
// seems "useRawName" is a misleading choice of variable name. For the same
147+
// reason, the checks for "_quoted" and "rowid" looks redundant. If you remove
148+
// those checks, then the double checks for total length can be reduced to one.
149+
// But I will leave it like this for now to make it look similar. /Oskar 2016-08-20
150+
bool useRawName = _name.Length + suffix.Length <= maxAliasLength &&
151+
!_quoted &&
152+
!StringHelper.EqualsCaseInsensitive(_name, "rowid");
153+
if (!useRawName)
150154
{
151-
return alias + suffix;
155+
if (suffix.Length >= maxAliasLength)
156+
{
157+
throw new MappingException(
158+
string.Format(
159+
"Unique suffix {0} length must be less than maximum {1} characters.",
160+
suffix,
161+
maxAliasLength));
162+
}
163+
if (alias.Length + suffix.Length > maxAliasLength)
164+
alias = alias.Substring(0, maxAliasLength - suffix.Length);
152165
}
166+
return alias + suffix;
153167
}
154168

155169
public string GetAlias(Dialect.Dialect dialect, Table table)
156170
{
157-
return GetAlias(dialect) + table.UniqueInteger + StringHelper.Underscore;
171+
string suffix = table.UniqueInteger.ToString() + StringHelper.Underscore;
172+
int maxAliasLength = dialect.MaxAliasLength - suffix.Length;
173+
return GetAlias(maxAliasLength) + suffix;
158174
}
159175

160176

0 commit comments

Comments
 (0)