-
Notifications
You must be signed in to change notification settings - Fork 934
WIP Concat should return supplied string type #2966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 6 commits
f5f2613
efafac1
377280a
79461cf
b2fc289
dd9f1cf
535fcb2
68b66f2
0056a64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1132,6 +1132,59 @@ public void Concat() | |
} | ||
} | ||
|
||
[Test] | ||
public void ConcatAnsiFirstParam() | ||
{ | ||
if (!TestDialect.SupportsAnsiString) | ||
Assert.Ignore("AnsiString type is not supported by dialect."); | ||
|
||
var nickName = "abcdef"; | ||
using (ISession s = OpenSession()) | ||
using (var t = s.BeginTransaction()) | ||
{ | ||
var a1 = new Human { NickName = nickName, Birthdate = DateTime.Today }; | ||
s.Save(a1); | ||
t.Commit(); | ||
} | ||
|
||
using (var logSpy = new SqlLogSpy()) | ||
using (ISession s = OpenSession()) | ||
{ | ||
var param = nickName + "gg"; | ||
var hql = "from Human a where concat(a.NickName, 'gg') = :param "; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if the second argument needs to be an Unicode string, because it contains some Unicode characters? I also think this test is not the most relevant we could devise for the #1166 troubles. The performance trouble due to type mismatch occurs mainly when statistics or an index can be used by the query, which implies we need a raw column on one side of the comparison, not a column on which a function is called. In #1166, the example yields an SQL like |
||
Animal result = (Animal) s.CreateQuery(hql).SetParameter("param", param).UniqueResult(); | ||
Assert.That(result, Is.Not.Null); | ||
Assert.That(logSpy.GetWholeLog(), Does.Contain("Type: AnsiString")); | ||
} | ||
} | ||
|
||
[KnownBug("Not fixed yet")] | ||
[Test] | ||
public void ConcatAnsiSecondParam() | ||
{ | ||
if (!TestDialect.SupportsAnsiString) | ||
Assert.Ignore("AnsiString type is not supported by dialect."); | ||
|
||
var nickName = "abcdef"; | ||
using (ISession s = OpenSession()) | ||
using (var t = s.BeginTransaction()) | ||
{ | ||
var a1 = new Human { NickName = nickName, Birthdate = DateTime.Today }; | ||
s.Save(a1); | ||
t.Commit(); | ||
} | ||
|
||
using (var logSpy = new SqlLogSpy()) | ||
using (ISession s = OpenSession()) | ||
{ | ||
var param = "gg" + nickName; | ||
var hql = "from Human a where concat('gg', a.NickName) = :param "; | ||
Animal result = (Animal) s.CreateQuery(hql).SetParameter("param", param).UniqueResult(); | ||
Assert.That(result, Is.Not.Null); | ||
Assert.That(logSpy.GetWholeLog(), Does.Contain("Type: AnsiString")); | ||
} | ||
} | ||
|
||
[Test] | ||
public void HourMinuteSecond() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,7 +101,7 @@ protected Dialect() | |
RegisterFunction("cast", new CastFunction()); | ||
RegisterFunction("transparentcast", new TransparentCastFunction()); | ||
RegisterFunction("extract", new AnsiExtractFunction()); | ||
RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "(", " || ", ")")); | ||
RegisterFunction("concat", new VarArgsSQLFunction("(", " || ", ")")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is an invalid change. It is not the first parameter which matters, but all parameters. As pointed in my first comment, all parameters must be ANSI strings for the return type to be an ANSI string. By not specifying the return type, we let NHibernate infer the returned type from the first parameter, which is then incorrect if the first is an ANSI string but not all others. It is also worst to incorrectly type something as an ANSI string than incorrectly type something as an Unicode string: the former may cause garbled text and performance issues, while the later may only cause performance issues. (Well, since with SQL Server 2019, varchar/char can be UTF-8 encoded, the former in such case could not have the garbled text issue. But that remains a corner case for now I think.) So I think this change is a regression. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case of simple comparison To me this case is not much of a difference. It's just an assumption that's used for type detection for not specified explicitly parameter types. So I don't think any garbled text is possible here (only wrong comparisons results, the same as with simple comparison) But OK let's be on a safe side... |
||
|
||
// the syntax of current_timestamp is extracted from H3.2 tests | ||
// - test\hql\ASTParserLoadingTest.java | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -257,7 +257,6 @@ protected virtual void RegisterStringFunctions() | |
RegisterFunction("char_length", new StandardSQLFunction("char_length", NHibernateUtil.Int32)); | ||
RegisterFunction("compare", new VarArgsSQLFunction(NHibernateUtil.Int32, "compare(", ",", ")")); | ||
RegisterFunction("compress", new VarArgsSQLFunction(NHibernateUtil.BinaryBlob, "compress(", ",", ")")); | ||
RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "(", "+", ")")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
RegisterFunction("csconvert", new VarArgsSQLFunction(NHibernateUtil.StringClob, "csconvert(", ",", ")")); | ||
RegisterFunction("decompress", new VarArgsSQLFunction(NHibernateUtil.BinaryBlob, "decompress(", ",", ")")); | ||
RegisterFunction("decrypt", new VarArgsSQLFunction(NHibernateUtil.BinaryBlob, "decrypt(", ",", ")")); | ||
|
Uh oh!
There was an error while loading. Please reload this page.