// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Threading.Tasks;
using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit.Abstractions;

namespace EntityFrameworkCore.Jet.FunctionalTests.Query
{
    public class FunkyDataQueryJetTest : FunkyDataQueryTestBase<FunkyDataQueryJetTest.FunkyDataQueryJetFixture>
    {
        public FunkyDataQueryJetTest(FunkyDataQueryJetFixture fixture, ITestOutputHelper testOutputHelper)
            : base(fixture)
        {
            Fixture.TestSqlLoggerFactory.Clear();
            //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
        }

        public override async Task String_contains_on_argument_with_wildcard_constant(bool isAsync)
        {
            await base.String_contains_on_argument_with_wildcard_constant(isAsync);

            AssertSql(
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE `f`.`FirstName` LIKE '%[%]B%'
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE `f`.`FirstName` LIKE '%a[_]%'
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE `f`.`FirstName` LIKE NULL
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE `f`.`FirstName` LIKE '%[_]Ba[_]%'
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE NOT (`f`.`FirstName` LIKE '%[%]B[%]a[%]r%')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE NOT (`f`.`FirstName` LIKE NULL)
    """);
        }

        public override async Task String_contains_on_argument_with_wildcard_parameter(bool isAsync)
        {
            await base.String_contains_on_argument_with_wildcard_parameter(isAsync);

            AssertSql(
                $@"{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE ({AssertSqlHelper.Parameter("@__prm1_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm1_0")}, 1) > 0",
                //
                $@"{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE ({AssertSqlHelper.Parameter("@__prm2_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm2_0")}, 1) > 0",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE (NULL LIKE '') OR INSTR(1, `f`.`FirstName`, NULL, 1) > 0",
                //
                $@"{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE ({AssertSqlHelper.Parameter("@__prm4_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm4_0")}, 1) > 0",
                //
                $@"{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE ({AssertSqlHelper.Parameter("@__prm5_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm5_0")}, 1) > 0",
                //
                $@"{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE NOT (({AssertSqlHelper.Parameter("@__prm6_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm6_0")}, 1) > 0)",
                //
                $@"{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE NOT (({AssertSqlHelper.Parameter("@__prm7_0")} LIKE '') OR INSTR(1, `f`.`FirstName`, {AssertSqlHelper.Parameter("@__prm7_0")}, 1) > 0)",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE NOT ((NULL LIKE '') OR INSTR(1, `f`.`FirstName`, NULL, 1) > 0)");
        }

        public override async Task String_contains_on_argument_with_wildcard_column(bool isAsync)
        {
            await base.String_contains_on_argument_with_wildcard_column(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE (`f0`.`LastName` LIKE '') OR INSTR(1, `f`.`FirstName`, `f0`.`LastName`, 1) > 0");
        }

        public override async Task String_contains_on_argument_with_wildcard_column_negated(bool isAsync)
        {
            await base.String_contains_on_argument_with_wildcard_column_negated(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE NOT ((`f0`.`LastName` LIKE '') OR INSTR(1, `f`.`FirstName`, `f0`.`LastName`, 1) > 0)");
        }

        public override async Task String_starts_with_on_argument_with_wildcard_constant(bool isAsync)
        {
            await base.String_starts_with_on_argument_with_wildcard_constant(isAsync);

            AssertSql(
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '[%]B%')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE 'a[_]%')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '[_]Ba[_]%')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND NOT (`f`.`FirstName` LIKE '[%]B[%]a[%]r%')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """);
        }

        public override async Task String_starts_with_on_argument_with_wildcard_parameter(bool isAsync)
        {
            await base.String_starts_with_on_argument_with_wildcard_parameter(isAsync);

            AssertSql(
                $@"{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm1_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm1_0")})) = {AssertSqlHelper.Parameter("@__prm1_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm2_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm2_0")})) = {AssertSqlHelper.Parameter("@__prm2_0")})",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE 0 = 1",
                //
                $@"{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm4_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm4_0")})) = {AssertSqlHelper.Parameter("@__prm4_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm5_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm5_0")})) = {AssertSqlHelper.Parameter("@__prm5_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm6_0")} <> '' AND (`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm6_0")})) <> {AssertSqlHelper.Parameter("@__prm6_0")}",
                //
                $@"{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm7_0")} <> '' AND (`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm7_0")})) <> {AssertSqlHelper.Parameter("@__prm7_0")}",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE 0 = 1");
        }

        public override async Task String_starts_with_on_argument_with_bracket(bool isAsync)
        {
            await base.String_starts_with_on_argument_with_bracket(isAsync);

            AssertSql(
    """
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '[[]%')
    """,
                    //
                    """
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE 'B[[]%')
    """,
                    //
                    """
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE 'B[[][[]a[^]%')
    """,
                    //
                    $"""
    @__prm1_0='[' (Size = 255)
    @__prm1_0='[' (Size = 255)
    @__prm1_0='[' (Size = 255)
    
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE {AssertSqlHelper.Parameter("@__prm1_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm1_0")})) = {AssertSqlHelper.Parameter("@__prm1_0")})
    """,
                    //
                    $"""
    @__prm2_0='B[' (Size = 255)
    @__prm2_0='B[' (Size = 255)
    @__prm2_0='B[' (Size = 255)
    
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE {AssertSqlHelper.Parameter("@__prm2_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm2_0")})) = {AssertSqlHelper.Parameter("@__prm2_0")})
    """,
                    //
                    $"""
    @__prm3_0='B[[a^' (Size = 255)
    @__prm3_0='B[[a^' (Size = 255)
    @__prm3_0='B[[a^' (Size = 255)
    
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE {AssertSqlHelper.Parameter("@__prm3_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm3_0")})) = {AssertSqlHelper.Parameter("@__prm3_0")})
    """,
                    //
                    """
    SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`
    FROM `FunkyCustomers` AS `f`
    WHERE `f`.`LastName` = '' OR ((`f`.`FirstName` IS NOT NULL) AND (`f`.`LastName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN(`f`.`LastName`)) = `f`.`LastName`)
    """);
        }

        public override async Task String_starts_with_on_argument_with_wildcard_column(bool isAsync)
        {
            await base.String_starts_with_on_argument_with_wildcard_column(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE `f0`.`LastName` = '' OR ((`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN(`f0`.`LastName`)) = `f0`.`LastName`)");
        }

        public override async Task String_starts_with_on_argument_with_wildcard_column_negated(bool isAsync)
        {
            await base.String_starts_with_on_argument_with_wildcard_column_negated(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE (`f0`.`LastName` <> '' OR (`f0`.`LastName` IS NULL)) AND (`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND LEFT(`f`.`FirstName`, LEN(`f0`.`LastName`)) <> `f0`.`LastName`");
        }

        public override async Task String_ends_with_on_argument_with_wildcard_constant(bool isAsync)
        {
            await base.String_ends_with_on_argument_with_wildcard_constant(isAsync);

            AssertSql(
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '%[%]B')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '%a[_]')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND (`f`.`FirstName` LIKE '%[_]Ba[_]')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE (`f`.`FirstName` IS NOT NULL) AND NOT (`f`.`FirstName` LIKE '%[%]B[%]a[%]r')
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """,
                //
                """
    SELECT `f`.`FirstName`
    FROM `FunkyCustomers` AS `f`
    WHERE 0 = 1
    """);
        }

        public override async Task String_ends_with_on_argument_with_wildcard_parameter(bool isAsync)
        {
            await base.String_ends_with_on_argument_with_wildcard_parameter(isAsync);

            AssertSql(
                $@"{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm1_0='%B' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm1_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm1_0")})) = {AssertSqlHelper.Parameter("@__prm1_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm2_0='a_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm2_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm2_0")})) = {AssertSqlHelper.Parameter("@__prm2_0")})",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE 0 = 1",
                //
                $@"{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm4_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm4_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm4_0")})) = {AssertSqlHelper.Parameter("@__prm4_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm5_0='_Ba_' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm5_0")} = '' OR ((`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm5_0")})) = {AssertSqlHelper.Parameter("@__prm5_0")})",
                //
                $@"{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm6_0='%B%a%r' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm6_0")} <> '' AND (`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm6_0")})) <> {AssertSqlHelper.Parameter("@__prm6_0")}",
                //
                $@"{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}
{AssertSqlHelper.Declaration("@__prm7_0='' (Size = 255)")}

SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE {AssertSqlHelper.Parameter("@__prm7_0")} <> '' AND (`f`.`FirstName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN({AssertSqlHelper.Parameter("@__prm7_0")})) <> {AssertSqlHelper.Parameter("@__prm7_0")}",
                //
                $@"SELECT `f`.`FirstName`
FROM `FunkyCustomers` AS `f`
WHERE 0 = 1");
        }

        public override async Task String_ends_with_on_argument_with_wildcard_column(bool isAsync)
        {
            await base.String_ends_with_on_argument_with_wildcard_column(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE `f0`.`LastName` = '' OR ((`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) = `f0`.`LastName`)");
        }

        public override async Task String_ends_with_on_argument_with_wildcard_column_negated(bool isAsync)
        {
            await base.String_ends_with_on_argument_with_wildcard_column_negated(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE (`f0`.`LastName` <> '' OR (`f0`.`LastName` IS NULL)) AND (`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) <> `f0`.`LastName`");
        }

        public override async Task String_ends_with_inside_conditional(bool isAsync)
        {
            await base.String_ends_with_inside_conditional(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE IIF(`f0`.`LastName` = '' OR ((`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) = `f0`.`LastName`), TRUE, FALSE) = TRUE");
        }

        public override async Task String_ends_with_inside_conditional_negated(bool isAsync)
        {
            await base.String_ends_with_inside_conditional_negated(isAsync);

            AssertSql(
                $@"SELECT `f`.`FirstName` AS `fn`, `f0`.`LastName` AS `ln`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE IIF((`f0`.`LastName` <> '' OR (`f0`.`LastName` IS NULL)) AND (`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) <> `f0`.`LastName`, TRUE, FALSE) = TRUE");
        }

        public override async Task String_ends_with_equals_nullable_column(bool isAsync)
        {
            await base.String_ends_with_equals_nullable_column(isAsync);

            AssertSql(
                $@"SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`, `f0`.`Id`, `f0`.`FirstName`, `f0`.`LastName`, `f0`.`NullableBool`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE IIF((`f0`.`LastName` = '' AND (`f0`.`LastName` IS NOT NULL)) OR ((`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) = `f0`.`LastName`), TRUE, FALSE) = `f`.`NullableBool`");
        }

        public override async Task String_ends_with_not_equals_nullable_column(bool isAsync)
        {
            await base.String_ends_with_not_equals_nullable_column(isAsync);

            AssertSql(
                $@"SELECT `f`.`Id`, `f`.`FirstName`, `f`.`LastName`, `f`.`NullableBool`, `f0`.`Id`, `f0`.`FirstName`, `f0`.`LastName`, `f0`.`NullableBool`
FROM `FunkyCustomers` AS `f`,
`FunkyCustomers` AS `f0`
WHERE IIF((`f0`.`LastName` = '' AND (`f0`.`LastName` IS NOT NULL)) OR ((`f`.`FirstName` IS NOT NULL) AND (`f0`.`LastName` IS NOT NULL) AND RIGHT(`f`.`FirstName`, LEN(`f0`.`LastName`)) = `f0`.`LastName`), TRUE, FALSE) <> `f`.`NullableBool` OR (`f`.`NullableBool` IS NULL)");
        }

        protected override void ClearLog()
            => Fixture.TestSqlLoggerFactory.Clear();

        private void AssertSql(params string[] expected)
            => Fixture.TestSqlLoggerFactory.AssertBaseline(expected);

        public class FunkyDataQueryJetFixture : FunkyDataQueryFixtureBase
        {
            public TestSqlLoggerFactory TestSqlLoggerFactory => (TestSqlLoggerFactory)ListLoggerFactory;

            protected override ITestStoreFactory TestStoreFactory => JetTestStoreFactory.Instance;
        }
    }
}
