Skip to content

Commit d98a279

Browse files
committed
NH-2408 - Fix locks application to tables with schema and/or catalog names and correct handle quoted table names in union subclasses by MsSql2000Dialect.LockHintAppender
1 parent 58c815e commit d98a279

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

src/NHibernate.Test/DialectTest/LockHintAppenderFixture.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,37 @@ public void ShouldIgnoreCasing()
5555
{
5656
const string expectedQuery =
5757
"select Id, Name FROM (select Id, Name FROM Employee with (updlock, rowlock) union all select Id, Name from Manager with (updlock, rowlock)) as person";
58-
58+
59+
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
60+
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
61+
}
62+
63+
[Test]
64+
public void ShouldHandleExplicitSchemas()
65+
{
66+
const string expectedQuery =
67+
"select Id, Name from (select Id, Name FROM dbo.Employee with (updlock, rowlock) union all select Id, Name from Manager with (updlock, rowlock)) as person";
68+
69+
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
70+
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
71+
}
72+
73+
[Test]
74+
public void ShouldHandleExplicitSchemasAndDbNames()
75+
{
76+
const string expectedQuery =
77+
"select Id, Name from (select Id, Name FROM nhibernate.dbo.Employee with (updlock, rowlock) union all select Id, Name from Manager with (updlock, rowlock)) as person";
78+
79+
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
80+
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
81+
}
82+
83+
[Test]
84+
public void ShouldHandleExplicitSchemasAndDbNamesWithSpacesBetweenNameParts()
85+
{
86+
const string expectedQuery =
87+
"select Id, Name from (select Id, Name FROM nhibernate .dbo. Employee with (updlock, rowlock) union all select Id, Name from Manager with (updlock, rowlock)) as person";
88+
5989
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
6090
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
6191
}
@@ -70,6 +100,26 @@ public void ShouldHandleEscapingInSubselect()
70100
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
71101
}
72102

103+
[Test]
104+
public void ShouldHandleEscapingWithWhitespacesInSubselect()
105+
{
106+
const string expectedQuery =
107+
"select Id, Name from (select Id, Name from [Empl oyee] with (updlock, rowlock) union all select Id, Name from [Man ager] with (updlock, rowlock)) as person";
108+
109+
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
110+
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
111+
}
112+
113+
[Test]
114+
public void ShouldHandleEscapingWithSquareBracketsInSubselect()
115+
{
116+
const string expectedQuery =
117+
"select Id, Name from (select Id, Name from [Empl ]]oyee] with (updlock, rowlock) union all select Id, Name from [Manager] with (updlock, rowlock)) as person";
118+
119+
var result = _appender.AppendLockHint(new SqlString(expectedQuery.Replace(MsSql2000LockHint, string.Empty)));
120+
Assert.That(result.ToString(), Is.EqualTo(expectedQuery));
121+
}
122+
73123
[Test]
74124
public void ShouldHandleMultilineQuery()
75125
{

src/NHibernate/Dialect/MsSql2000Dialect.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,13 @@ public override bool IsKnownToken(string currentToken, string nextToken)
519519

520520
public struct LockHintAppender
521521
{
522-
private static readonly Regex FromClauseTableNameRegex = new Regex(@"from\s+\[?(\w+)\]?", RegexOptions.IgnoreCase | RegexOptions.Multiline);
522+
private const string UnescapedNameRegex = @"\w+";
523+
private const string EscapedNameRegex = @"\[([^\]]|\]\])+\]";
524+
private const string NameRegex = "(" + UnescapedNameRegex + "|" + EscapedNameRegex + ")";
525+
private const string NameSeparatorRegex = @"\s*\.\s*";
526+
private const string FromTableNameRegex = @"from\s+(" + NameRegex + NameSeparatorRegex + "){0,2}" + NameRegex;
527+
528+
private static readonly Regex FromClauseTableNameRegex = new Regex(FromTableNameRegex, RegexOptions.IgnoreCase | RegexOptions.Multiline);
523529

524530
private readonly MsSql2000Dialect _dialect;
525531
private readonly IDictionary<string, LockMode> _aliasedLockModes;
@@ -546,7 +552,7 @@ public SqlString AppendLockHint(SqlString sql)
546552
{
547553
var result = new SqlStringBuilder();
548554

549-
foreach (object part in sql.Parts)
555+
foreach (object part in sql)
550556
{
551557
if (part == Parameter.Placeholder)
552558
{

0 commit comments

Comments
 (0)