Skip to content
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

Invalid sub-query SQL generated #4160

Open
brd-mikek opened this issue Jun 8, 2023 · 13 comments · May be fixed by #4180
Open

Invalid sub-query SQL generated #4160

brd-mikek opened this issue Jun 8, 2023 · 13 comments · May be fixed by #4180
Assignees
Labels
status: has-pr There is active PR for issue type: bug
Milestone

Comments

@brd-mikek
Copy link

Please see demo project attached.
We are facing an issue where when we're trying to use sub-query, Linq2Db is creating an invalid SQL query.
Below is the query that gets executed when we run the scenario.
As you can see, the inner select statement returns 2 values in this scenario which results in a "ORA-00913: too many values" error.

------Linq------

var data = (
    from pe in db.PERSON
    select new
    {
        CURRENCYCALCULATEDSYMBOL = (from cc in db.CITY
                                    where cc.CITYCODE == pe.CITYCODE
                                    select cc.CITYNAME).FirstOrDefault(),
    }).Distinct().ToList();

------Linq------

------Generated SQL------

DECLARE @take Int32
SET     @take = 1

SELECT DISTINCT
        (
                SELECT
                        cc.CITYNAME,
                        1
                FROM
                        CITY cc
                WHERE
                        (cc.CITYCODE = pe.CITYCODE OR cc.CITYCODE IS NULL AND pe.CITYCODE IS NULL)
                FETCH NEXT :take ROWS ONLY
        ),
        t1.CITYNAME,
        t1."is_empty"
FROM
        PERSON pe
                OUTER APPLY (
                        SELECT
                                cc.CITYNAME,
                                1 as "is_empty"
                        FROM
                                CITY cc
                        WHERE
                                (cc.CITYCODE = pe.CITYCODE OR cc.CITYCODE IS NULL AND pe.CITYCODE IS NULL)
                        FETCH NEXT :take ROWS ONLY
                ) t1

------Generated SQL------

LinqToDbIssueDemo.zip

@brd-mikek
Copy link
Author

Another question. Your old versions used to generate sub-queries and your new versions generate OUTER APPLY clauses. I liked sub-queries better. Is there a way to choose old behavior?

@MaceWindu
Copy link
Contributor

Try to add AsSubquery() call, maybe it will help

@brd-mikek
Copy link
Author

Hey guys, any update on this?
We want to upgrade our code from old version (2.9.6) for that we need a couple of bugs resolved - this one and also 4163 and 4167.

@MaceWindu
Copy link
Contributor

Will try to check it in next couple of weeks. Don't have much time currently

@sdanyliv
Copy link
Member

Try the following query as workaround:

var data = (
    from pe in db.PERSON
    from cc in db.CITY
      .Where(cc => cc.CITYCODE == pe.CITYCODE)
      .Take(1)
      .DefaultIfEmpty()
    select new
    {
        CURRENCYCALCULATEDSYMBOL = cc.CITYNAME,
    }).Distinct().ToList();

@brd-mikek
Copy link
Author

Try the following query as workaround:

var data = (
    from pe in db.PERSON
    from cc in db.CITY
      .Where(cc => cc.CITYCODE == pe.CITYCODE)
      .Take(1)
      .DefaultIfEmpty()
    select new
    {
        CURRENCYCALCULATEDSYMBOL = cc.CITYNAME,
    }).Distinct().ToList();

Thanks for that.
However problem is not in writing new queries.
We have (big!) codebase that we want to upgrade to new version.
We need to be sure that our existing code still works after upgrade.

@MaceWindu MaceWindu added this to the 5.3.0 milestone Jun 24, 2023
@MaceWindu MaceWindu self-assigned this Jun 25, 2023
@MaceWindu
Copy link
Contributor

MaceWindu commented Jun 25, 2023

Change happended in 3.0.0-preview.2

Old sql

SELECT DISTINCT
        (
                SELECT
                        cc_1.CITYNAME
                FROM
                        CITY cc_1
                WHERE
                        ROWNUM <= 1 AND (cc_1.CITYCODE IS NULL AND pe.CITYCODE IS NULL OR cc_1.CITYCODE = pe.CITYCODE)
        ),
        (
                SELECT
                        cc_2.CITYNAME
                FROM
                        CITY cc_2
                WHERE
                        ROWNUM <= 1 AND (cc_2.CITYCODE IS NULL AND pe.CITYCODE IS NULL OR cc_2.CITYCODE = pe.CITYCODE)
        )
FROM
        PERSON pe

@MaceWindu
Copy link
Contributor

Probably by this PR #2087

@MaceWindu
Copy link
Contributor

Actually both queries (old version and new) look strange. Providers without APPLY support generate more sane SQL:

SELECT DISTINCT
        (
                SELECT
                        cc.CITYNAME
                FROM
                        CITY cc
                WHERE
                        (cc.CITYCODE = pe.CITYCODE OR cc.CITYCODE IS NULL AND pe.CITYCODE IS NULL) AND
                        ROWNUM <= :take
        )
FROM
        PERSON pe

@MaceWindu MaceWindu linked a pull request Jun 25, 2023 that will close this issue
@MaceWindu MaceWindu added the status: has-pr There is active PR for issue label Jun 25, 2023
@brd-mikek
Copy link
Author

Honestly, I'm not sure why you added support for APPLY.
It seems to me that the same can be achieved with simple JOIN.
Better to have one approach than two in my opinion.

Wondering what was your motivation?
Wondering also, are there options to generate JOIN instead of APPLY?

@MaceWindu
Copy link
Contributor

While APPLY is not being necessary in this specific case, we still need it for more complex queries.
You can set PreferApply option to false to not force APPLY when we can use joins

@brd-mikek
Copy link
Author

Hey guys!
Any update on this issue by any chance?
We raised this one and a couple others (4163, 4167, 4172) and they stop us from upgrading to latest version.

@brd-mikek
Copy link
Author

Hi guys!
This bug was open for more than 3 month.
Wondering if this project is still supported?
Is there any way we can contribute?

@MaceWindu MaceWindu modified the milestones: 5.3.0, 5.3.1 Oct 9, 2023
@MaceWindu MaceWindu modified the milestones: 5.3.3, 5.4.0, In-progress Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: has-pr There is active PR for issue type: bug
Development

Successfully merging a pull request may close this issue.

3 participants