Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1a99c0f
Improved tests of string operations' compilers
alex-kulakov Oct 31, 2024
b4022de
Improve string.Trim/TrimStart/TrimEnd support
alex-kulakov Nov 1, 2024
bf44a10
MySQL: Fix wrong translation of NullIf
alex-kulakov Dec 26, 2024
0c0b1d1
MySQL: Fix Pad operations
alex-kulakov Dec 27, 2024
5165b4b
Merge branch 'master' into master-stringoperations-imp
alex-kulakov Dec 28, 2024
36062d4
SQLite: Fix string.Length translation and implement PadLeft/PadRight …
alex-kulakov Dec 28, 2024
71e8ef0
AutoBuildTest: Introduce GlobalSession/GlobalTransaction for read-onl…
alex-kulakov Jan 14, 2025
d1ac731
More tests use global session
alex-kulakov Jan 14, 2025
94a6020
AutoBuildTest: Fixed error message on attempt to access uninitialized…
alex-kulakov Jan 15, 2025
9b00bb8
Merge pull request #417 from DataObjects-NET/7.1-global-session-in-tests
alex-kulakov Jan 15, 2025
0c71b40
Move test to correct namespace
alex-kulakov Jan 15, 2025
84f7596
Add tests that checks Validator results
alex-kulakov Jan 20, 2025
6077735
Explicitlly set KeyGeneratorKind.None instead of implicit conversion
alex-kulakov Jan 20, 2025
5a807f3
Write warning to build log about change of generator kind
alex-kulakov Jan 20, 2025
8b9f50d
caviar->caveat in comments
alex-kulakov Jan 21, 2025
f87d243
Improve changelog
alex-kulakov Jan 21, 2025
326730b
Merge pull request #419 from DataObjects-NET/7.1-hierarchydef-validation
alex-kulakov Jan 21, 2025
0da23ca
Fix misspelling of "Length"
alex-kulakov Jan 22, 2025
d487fb6
Remove commented code
alex-kulakov Jan 22, 2025
e77d2ec
Rename function
alex-kulakov Jan 22, 2025
e281961
Improve changelog
alex-kulakov Jan 22, 2025
79981d1
Postgresql: Declare the same setting for nulls in indexes as in order…
alex-kulakov Jan 22, 2025
ee66c74
Fix misspelling of "Length" part 2
alex-kulakov Jan 24, 2025
06d0f1c
Improve changelog
alex-kulakov Jan 24, 2025
c2edc24
Merge pull request #420 from DataObjects-NET/7.1-pgsql-nulls-order-in…
alex-kulakov Jan 24, 2025
b98643e
Bump version ot 7.1.4
alex-kulakov Jan 24, 2025
b592eff
Merge branch '7.1'
alex-kulakov Jan 27, 2025
24fc39f
Fix warnings after merge
alex-kulakov Jan 27, 2025
876b45a
Merge branch 'master' into master-stringoperations-imp
alex-kulakov Jan 27, 2025
b36f950
Merge pull request #421 from DataObjects-NET/master-stringoperations-imp
alex-kulakov Jan 28, 2025
b915f07
Merge remote-tracking branch 'upstream/master' into mergeUpstream
SergeiPavlov Jan 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ChangeLog/7.2.0-Beta-2-dev.txt
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
[main] Upgrade hints change names of constructors' string parameters for better understanding of what suppose to be in them.
[main] Upgrade hints change names of constructors' string parameters for better understanding of what suppose to be in them.
[main] Improved string operations Trim/TrimStart/TrimEnd support
[mysql] SqlDml.NullIf function now correctly translated
[mysql] Improved support for string.PadLeft/PadRight opertaions
[sqlite] Fixed string.Lenght translation
[sqlite] Added support for string.PadLeft/PadRight operations
2 changes: 1 addition & 1 deletion Orm/Xtensive.Orm.MySql/Sql.Drivers.MySql/v5_0/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public override void Visit(SqlFunctionCall node)
return;
case SqlFunctionType.PadLeft:
case SqlFunctionType.PadRight:
SqlHelper.GenericPad(node).AcceptVisitor(this);
SqlHelper.GenericPad(node, true).AcceptVisitor(this);
return;
case SqlFunctionType.Rand:
SqlDml.FunctionCall(translator.TranslateToString(SqlFunctionType.Rand)).AcceptVisitor(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ public override void Translate(IOutput output, SqlFunctionType type)
case SqlFunctionType.CurrentUser:
_ = output.Append("CURRENT_USER()"); break;
case SqlFunctionType.SessionUser: _ = output.Append("SESSION_USER()"); break;
case SqlFunctionType.NullIf: _ = output.Append("IFNULL"); break;
//datetime/timespan
case SqlFunctionType.DateTimeTruncate: _ = output.Append("DATE"); break;
case SqlFunctionType.CurrentDate: _ = output.Append("CURDATE()"); break;
Expand Down
39 changes: 38 additions & 1 deletion Orm/Xtensive.Orm.Sqlite/Sql.Drivers.Sqlite/v3/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,11 @@ public override void Visit(SqlFunctionCall node)
var arguments = node.Arguments;
switch (node.FunctionType) {
case SqlFunctionType.CharLength:
(SqlDml.FunctionCall("LENGTH", arguments) / 2).AcceptVisitor(this);
SqlDml.FunctionCall("LENGTH", arguments).AcceptVisitor(this);
return;
case SqlFunctionType.PadLeft:
case SqlFunctionType.PadRight:
Visit(EmulateLpadRpad(arguments, node.FunctionType is SqlFunctionType.PadLeft));
return;
case SqlFunctionType.Concat:
var nod = arguments[0];
Expand Down Expand Up @@ -631,6 +632,42 @@ private static SqlDateTimePart ConvertDateTimeOffsetPartToDateTimePart(SqlDateTi
};
}

private static SqlCase EmulateLpadRpad(IReadOnlyList<SqlExpression> arguments, bool isLpad)
{
var operand = arguments[0];
var charcount = arguments[1];
if (charcount is not SqlLiteral<int> intWidth) {
// Since we emulate function with contatination, we need to know total width
// to calculate prefix
throw SqlHelper.NotSupported("PadLeft/PadRight with expressions as total width.");
}
var totalWidth = intWidth.Value;

var padChar = arguments switch {
_ when arguments.Count == 3 && arguments[2] is SqlLiteral<char> charLiteral => charLiteral.Value,
_ when arguments.Count == 2 => ' ',
_ => throw new NotSupportedException()
};

var paddingString = SqlDml.Literal(new string(Enumerable.Repeat(padChar, intWidth.Value).ToArray()));

var padExpression = isLpad
? SqlDml.Substring(
SqlDml.Concat(paddingString, operand),
SqlDml.Literal(-totalWidth - 1),// handles '+1' operation in translation of substring function call
SqlDml.Literal(totalWidth))
: SqlDml.Substring(
SqlDml.Concat(operand, paddingString),
SqlDml.Literal(0), // handles '+1' operation in translation of substring function call
SqlDml.Literal(totalWidth));

var @case = SqlDml.Case();
_ = @case.Add(SqlDml.CharLength(operand) >= charcount, operand);
@case.Else = padExpression;
return @case;
}


// Constructors

/// <param name="driver">The driver.</param>
Expand Down
112 changes: 0 additions & 112 deletions Orm/Xtensive.Orm.Tests/Linq/SelectTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -768,118 +768,6 @@ where invoice.InvoiceId > 0 && invoice.InvoiceId < 50
}
}

[Test]
public void SelectStringIndexerTest()
{
var result =
Session.Query.All<Customer>()
.Select(c => new {
String = c.CustomerId,
Char0 = c.Email[0],
Char1 = c.Email[1],
Char2 = c.Email[2],
Char3 = c.Email[3],
Char4 = c.Email[4],
})
.ToArray()
.OrderBy(item => item.String)
.ToArray();
var expected = Customers
.Select(c => new {
String = c.CustomerId,
Char0 = c.Email[0],
Char1 = c.Email[1],
Char2 = c.Email[2],
Char3 = c.Email[3],
Char4 = c.Email[4],
})
.OrderBy(item => item.String)
.ToArray();
Assert.AreEqual(expected.Length, result.Length);
for (var i = 0; i < expected.Length; i++) {
Assert.AreEqual(expected[0].String, result[0].String);
Assert.AreEqual(expected[0].Char0, result[0].Char0);
Assert.AreEqual(expected[0].Char1, result[0].Char1);
Assert.AreEqual(expected[0].Char2, result[0].Char2);
Assert.AreEqual(expected[0].Char3, result[0].Char3);
Assert.AreEqual(expected[0].Char4, result[0].Char4);
}
}

[Test]
public void SelectIndexOfTest()
{
var _char = 'A';
var result =
Session.Query.All<Customer>()
.Select(c => new {
String = c.FirstName,
IndexOfChar = c.FirstName.IndexOf(_char),
IndexOfCharStart = c.FirstName.IndexOf(_char, 1),
IndexOfCharStartCount = c.FirstName.IndexOf(_char, 1, 1),
IndexOfString = c.FirstName.IndexOf(_char.ToString()),
IndexOfStringStart = c.FirstName.IndexOf(_char.ToString(), 1),
IndexOfStringStartCount = c.FirstName.IndexOf(_char.ToString(), 1, 1)
})
.ToArray()
.OrderBy(item => item.String)
.ToArray();
var expected = Customers
.Select(c => new {
String = c.FirstName,
IndexOfChar = c.FirstName.IndexOf(_char),
IndexOfCharStart = c.FirstName.IndexOf(_char, 1),
IndexOfCharStartCount = c.FirstName.IndexOf(_char, 1, 1),
IndexOfString = c.FirstName.IndexOf(_char.ToString()),
IndexOfStringStart = c.FirstName.IndexOf(_char.ToString(), 1),
IndexOfStringStartCount = c.FirstName.IndexOf(_char.ToString(), 1, 1)
})
.OrderBy(item => item.String)
.ToArray();
Assert.AreEqual(expected.Length, result.Length);
for (var i = 0; i < expected.Length; i++) {
Assert.AreEqual(expected[i].String, result[i].String);
Assert.AreEqual(expected[i].IndexOfChar, result[i].IndexOfChar);
Assert.AreEqual(expected[i].IndexOfCharStart, result[i].IndexOfCharStart);
Assert.AreEqual(expected[i].IndexOfCharStartCount, result[i].IndexOfCharStartCount);
Assert.AreEqual(expected[i].IndexOfString, result[i].IndexOfString);
Assert.AreEqual(expected[i].IndexOfStringStart, result[i].IndexOfStringStart);
Assert.AreEqual(expected[i].IndexOfStringStartCount, result[i].IndexOfStringStartCount);
}
}

[Test]
public void SelectStringContainsTest1()
{
Require.ProviderIs(StorageProvider.Sqlite | StorageProvider.SqlServer | StorageProvider.MySql);
var result =
Session.Query.All<Customer>()
.Where(c => c.FirstName.Contains('L'))
.OrderBy(c => c.CustomerId)
.ToArray();
var expected = Customers
.Where(c => c.FirstName.Contains('L') || c.FirstName.Contains('l'))
.OrderBy(c => c.CustomerId)
.ToArray();
Assert.IsTrue(expected.SequenceEqual(result));
}

[Test]
public void SelectStringContainsTest2()
{
Require.ProviderIsNot(StorageProvider.Sqlite | StorageProvider.SqlServer | StorageProvider.MySql);
var result =
Session.Query.All<Customer>()
.Where(c => c.FirstName.Contains('L'))
.OrderBy(c => c.CustomerId)
.ToArray();
var expected = Customers
.Where(c => c.FirstName.Contains('L'))
.OrderBy(c => c.CustomerId)
.ToArray();
Assert.IsTrue(expected.SequenceEqual(result));
}

[Test]
public void SelectDateTimeTimeSpanTest()
{
Expand Down
Loading