linq2db icon indicating copy to clipboard operation
linq2db copied to clipboard

Fix ~string.IsNullOrEmpty~ string.Length mapping for SQL CE/MSSQL

Open MaceWindu opened this issue 2 years ago • 21 comments

Fix #4138

MaceWindu avatar Jun 24 '23 11:06 MaceWindu

/azp run test-all

MaceWindu avatar Jun 24 '23 11:06 MaceWindu

Azure Pipelines successfully started running 1 pipeline(s).

azure-pipelines[bot] avatar Jun 24 '23 11:06 azure-pipelines[bot]

/azp run test-all

MaceWindu avatar Jun 24 '23 11:06 MaceWindu

Azure Pipelines failed to run 1 pipeline(s).

azure-pipelines[bot] avatar Jun 24 '23 11:06 azure-pipelines[bot]

/azp run test-all

MaceWindu avatar Jun 24 '23 11:06 MaceWindu

Azure Pipelines successfully started running 1 pipeline(s).

azure-pipelines[bot] avatar Jun 24 '23 11:06 azure-pipelines[bot]

Test baselines changed by this PR. Don't forget to merge/close baselines PR after this pr merged/closed.

linq2dbot avatar Jun 24 '23 16:06 linq2dbot

/azp run test-all

MaceWindu avatar Jun 24 '23 20:06 MaceWindu

Azure Pipelines successfully started running 1 pipeline(s).

azure-pipelines[bot] avatar Jun 24 '23 20:06 azure-pipelines[bot]

/azp run test-all

MaceWindu avatar Jun 25 '23 11:06 MaceWindu

Azure Pipelines successfully started running 1 pipeline(s).

azure-pipelines[bot] avatar Jun 25 '23 11:06 azure-pipelines[bot]

I don't get why some DBs think they have right to mess with user data interpretation....

MaceWindu avatar Jun 25 '23 11:06 MaceWindu

If people rely on old behavior of Length, it could be breaking change for them (MSSQL/SQLCE users only)

Still I think it is a bug that should be fixed as:

  • for .net mappings we try to emulate .net behavior when possible
  • for db-behavior users should use explicit mappings for database functions

MaceWindu avatar Jun 26 '23 14:06 MaceWindu

Perhaps wait until v6 then?

viceroypenguin avatar Jun 26 '23 14:06 viceroypenguin

I'm fine with it (I will need this fix at some point, but currently I'm stuck with 4.3.0, so it will not help me anyways if we release it now)

MaceWindu avatar Jun 26 '23 14:06 MaceWindu

If waiting till v6, I'm good with it

viceroypenguin avatar Jun 26 '23 14:06 viceroypenguin

I do not like this change at all as we fix very exotic case and break performance of all others. Lets keep previous behavior by default and add some settings to switch it to this implementation.

igor-tkachev avatar Jul 14 '23 04:07 igor-tkachev

I'm with @igor-tkachev on this one, I don't like this change.

  1. This is a massive breaking change for people who have fixed-length string columns in their DB such as char(50). This is common in legacy schemas and is the motivation why LEN would not count trailing spaces.

  2. I see linq2db as a thin predictable mapper over SQL, even if in some specific cases the behaviour of SQL and C# differ. These differences cannot all be efficiently erased, users have to be conscious of them and SQL semantics. Examples include: three-valued logic, null comparisons, empty string is null in Oracle, different datatypes range (e.g. DateTime), etc. I don't like creating complex, inefficient expression for minor edge cases, and depriving users from an easy access to straightforward SQL code.

It's surprising that "abc".Length does not convert to LEN('abc').

I think the best way to proceed is to keep everything as-is and provide FullLength() as a SQL extension for SQL Server provider. If SQL Server users don't want the native behaviour, they can use this new function instead.

jods4 avatar Jul 19 '23 09:07 jods4

Also I would add a method (configuration property) to switch default conversion to this new way.

igor-tkachev avatar Jul 19 '23 15:07 igor-tkachev

Also I would add a method (configuration property) to switch default conversion to this new way.

Yeah, if it is desirable for SQL Server users to change the default behavior of "abc".Length to the untrimmed way, I would make it an opt-in option in SQL Server provider-specific options, such as SqlServerOptions.TrimmedLength = false.

Did we get a lot of feedback on this? #4138 was opened recently but this behaviour has been in linq2db + Sql Server for years.

If there is a global option, I would make it change only the "".Length behaviour, so that regardless of your option you still have easy access to the other SQL code gen:

  • "".Length behavior is configurable (MSSQL provider-only) as you prefer (trimmed or non-trimmed);
  • Sql.Length() always predictably converts into LEN(..) so it's an escape hatch when TrimmedLength = false;
  • SqlServerExtensions.UntrimmedLength() always converts into an expression that doesn't trim, so it's an escape hatch when TrimmedLength = true.

jods4 avatar Jul 19 '23 16:07 jods4

Did we get a lot of feedback on this? #4138 was opened recently but this behaviour has been in linq2db + Sql Server for years.

This is the point. I have been using Sql Server for 25 years now and have never experienced this before.

igor-tkachev avatar Jul 19 '23 16:07 igor-tkachev