Skip to content

Commit 73123ee

Browse files
committed
GH3618 - Failed recognition of SQL comments
1 parent 0c9e442 commit 73123ee

File tree

2 files changed

+65
-32
lines changed

2 files changed

+65
-32
lines changed

src/NHibernate.Test/EngineTest/ParameterParserFixture.cs

+41-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using NHibernate.Engine.Query;
2+
using NSubstitute;
23
using NUnit.Framework;
34

45
namespace NHibernate.Test.EngineTest
@@ -19,8 +20,8 @@ FROM tablea
1920

2021
var recognizer = new ParamLocationRecognizer();
2122
ParameterParser.Parse(query, recognizer);
22-
ParamLocationRecognizer.NamedParameterDescription p;
23-
Assert.DoesNotThrow(() => p = recognizer.NamedParameterDescriptionMap["name"]);
23+
Assert.That(recognizer.NamedParameterDescriptionMap, Has.Count.EqualTo(1));
24+
Assert.That(recognizer.NamedParameterDescriptionMap, Contains.Key("name"));
2425
}
2526

2627
[Test]
@@ -30,14 +31,14 @@ public void CanFindParameterAfterInlineComment()
3031
@"
3132
SELECT id
3233
FROM tablea
33-
-- Comment with ' number 1
34+
-- Comment with ' :number 1
3435
WHERE Name = :name
3536
ORDER BY Name";
3637

3738
var recognizer = new ParamLocationRecognizer();
3839
ParameterParser.Parse(query, recognizer);
39-
ParamLocationRecognizer.NamedParameterDescription p;
40-
Assert.DoesNotThrow(() => p = recognizer.NamedParameterDescriptionMap["name"]);
40+
Assert.That(recognizer.NamedParameterDescriptionMap, Has.Count.EqualTo(1));
41+
Assert.That(recognizer.NamedParameterDescriptionMap, Contains.Key("name"));
4142
}
4243

4344
[Test]
@@ -54,9 +55,41 @@ FROM tablea
5455

5556
var recognizer = new ParamLocationRecognizer();
5657
ParameterParser.Parse(query, recognizer);
57-
ParamLocationRecognizer.NamedParameterDescription p;
58-
Assert.DoesNotThrow(() => p = recognizer.NamedParameterDescriptionMap["name"]);
59-
Assert.DoesNotThrow(() => p = recognizer.NamedParameterDescriptionMap["pizza"]);
58+
Assert.That(recognizer.NamedParameterDescriptionMap, Has.Count.EqualTo(2));
59+
Assert.That(recognizer.NamedParameterDescriptionMap, Contains.Key("name"));
60+
Assert.That(recognizer.NamedParameterDescriptionMap, Contains.Key("pizza"));
61+
}
62+
63+
[Test]
64+
public void IgnoresCommentsWithinQuotes()
65+
{
66+
string query =
67+
@"
68+
SELECT id
69+
FROM tablea WHERE Name = '
70+
-- :comment1
71+
' OR Name = '
72+
/* :comment2 */
73+
'
74+
-- :comment3
75+
/* :comment4 */
76+
ORDER BY Name + :pizza -- :comment5";
77+
78+
var recognizer = Substitute.For<ParameterParser.IRecognizer>();
79+
ParameterParser.Parse(query, recognizer);
80+
81+
//Only one parameter in the query
82+
recognizer.ReceivedWithAnyArgs(1).NamedParameter(default, default);
83+
recognizer.Received(1).NamedParameter("pizza", Arg.Any<int>());
84+
85+
//comment1 and comment2 are not really comments and therefore not parsed as blocks
86+
recognizer.DidNotReceive().Other(Arg.Is<string>(x => x.Contains("comment1")));
87+
recognizer.DidNotReceive().Other(Arg.Is<string>(x => x.Contains("comment2")));
88+
89+
//comment 3-5 are actual comments and therefore parsed as blocks
90+
recognizer.Received(1).Other(Arg.Is<string>(x => x.StartsWith("-- :comment3")));
91+
recognizer.Received(1).Other("/* :comment4 */");
92+
recognizer.Received(1).Other(Arg.Is<string>(x => x.StartsWith("-- :comment5")));
6093
}
6194
}
6295
}

src/NHibernate/Engine/Query/ParameterParser.cs

+24-24
Original file line numberDiff line numberDiff line change
@@ -48,47 +48,47 @@ public static void Parse(string sqlString, IRecognizer recognizer)
4848

4949
int stringLength = sqlString.Length;
5050
bool inQuote = false;
51-
bool afterNewLine = false;
5251
for (int indx = 0; indx < stringLength; indx++)
5352
{
5453
int currentNewLineLength;
5554

56-
// check comments
57-
if (indx + 1 < stringLength && sqlString.Substring(indx,2) == "/*")
55+
// check comments, unless in quote
56+
if (!inQuote)
5857
{
59-
var closeCommentIdx = sqlString.IndexOf("*/", indx + 2, StringComparison.Ordinal);
60-
recognizer.Other(sqlString.Substring(indx, (closeCommentIdx- indx)+2));
61-
indx = closeCommentIdx + 1;
62-
continue;
63-
}
64-
65-
if (afterNewLine && (indx + 1 < stringLength) && sqlString.Substring(indx, 2) == "--")
66-
{
67-
var closeCommentIdx = sqlString.IndexOfAnyNewLine(indx + 2, out currentNewLineLength);
68-
69-
string comment;
70-
if (closeCommentIdx == -1)
58+
if (indx + 1 < stringLength && sqlString.Substring(indx, 2) == "/*")
7159
{
72-
closeCommentIdx = sqlString.Length;
73-
comment = sqlString.Substring(indx);
60+
var closeCommentIdx = sqlString.IndexOf("*/", indx + 2, StringComparison.Ordinal);
61+
recognizer.Other(sqlString.Substring(indx, (closeCommentIdx - indx) + 2));
62+
indx = closeCommentIdx + 1;
63+
continue;
7464
}
75-
else
65+
66+
if ((indx + 1 < stringLength) && sqlString.Substring(indx, 2) == "--")
7667
{
77-
comment = sqlString.Substring(indx, closeCommentIdx - indx + currentNewLineLength);
68+
var closeCommentIdx = sqlString.IndexOfAnyNewLine(indx + 2, out currentNewLineLength);
69+
70+
string comment;
71+
if (closeCommentIdx == -1)
72+
{
73+
closeCommentIdx = sqlString.Length;
74+
comment = sqlString.Substring(indx);
75+
}
76+
else
77+
{
78+
comment = sqlString.Substring(indx, closeCommentIdx - indx + currentNewLineLength);
79+
}
80+
recognizer.Other(comment);
81+
indx = closeCommentIdx + currentNewLineLength - 1;
82+
continue;
7883
}
79-
recognizer.Other(comment);
80-
indx = closeCommentIdx + currentNewLineLength - 1;
81-
continue;
8284
}
8385

8486
if (sqlString.IsAnyNewLine(indx, out currentNewLineLength))
8587
{
86-
afterNewLine = true;
8788
indx += currentNewLineLength - 1;
8889
recognizer.Other(Environment.NewLine);
8990
continue;
9091
}
91-
afterNewLine = false;
9292

9393
char c = sqlString[indx];
9494
if (inQuote)

0 commit comments

Comments
 (0)