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

FromSql(): Support passing a preamble SQL string #4976

Open
Tracked by #21888
divega opened this issue Apr 4, 2016 · 17 comments
Open
Tracked by #21888

FromSql(): Support passing a preamble SQL string #4976

divega opened this issue Apr 4, 2016 · 17 comments

Comments

@divega
Copy link
Contributor

divega commented Apr 4, 2016

Currently whenever FromSql() detects a SQL string that does not start with the word SELECT, it treat it as a non-composable query and it evaluates the rest of the query on the client side.

Some SQL constructs such as Common Table Expressions are fully composable but cannot be treated like normal SELECT statements in that they cannot be simply pushed down inside FROM clauses to become derived tables for a new SELECT.

It should be possible to support composability with CTEs if they could be specified separately from the SELECT, e.g. consider the following LINQ query (based on issue #4780):

        var peamble = 
@"with postsCTE as (
   select Id, ReplyToPostId
   from Posts
   where Id = {0}
   union all
   select Parent.Id, Parent.ReplyToPostId
   from Posts Parent
     join postsCTE Son on Son.ReplyToPostId = Parent.Id)";

        var sql = 
@"select * 
from HierarchyPosts 
where RootId =
    (select top 1 Id 
    from PostsCTE 
    where ReplyToPostId is null)";

        var query = context.HierarchyPosts
            .FromSqlWithPreamble(preamble, query, postId)
            .OrderBy(x => x.ReplyToPostId ?? -1);

For it, we would need to generate SQL similar to this:

with postsCTE as (
   select Id, ReplyToPostId
   from Posts
   where Id = @p0
   union all
   select Parent.Id, Parent.ReplyToPostId
   from Posts Parent
     join postsCTE Son on Son.ReplyToPostId = Parent.Id)

SELECT *
FROM (select * 
    from HierarchyPosts 
    where RootId =
        (select top 1 Id 
        from PostsCTE 
        where ReplyToPostId is null)) AS q0
ORDER BY COALESCE(q0.ReplyToPostId, -1)
@bricelam
Copy link
Contributor

Reading up on WITH, these outlandish recursive queries in the SQLite docs are pretty epic.

@amattar
Copy link

amattar commented Aug 13, 2018

any update on this?

@bricelam
Copy link
Contributor

If you're interested in contributing, start here in RelationalEntityQueryableExpressionVisitor.

@bricelam bricelam added the help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. label Aug 13, 2018
@tjrobinson
Copy link

I've noticed a variation of this problem with simple queries (i.e. no CTE) where the query starts with a comment instead of the word SELECT.

In my example I'm reading the query as a string from an embedded resource then executing it with FromSql().

@roji
Copy link
Member

roji commented Mar 15, 2019

With the decision to stop doing client evaluation (#14935), does it make sense to stop doing any checks on the SQL altogether? If the user provides a non-composable SQL, they'd simply get a database error, which seems like the right thing...

@khellang
Copy link
Member

I'm hitting this as well. It would be nice to just stop validating SQL client-side and let the DB handle it, as @roji suggests...

@roji
Copy link
Member

roji commented Apr 16, 2019

Clearing milestone so we can discuss in triage.

@roji roji removed this from the Backlog milestone Apr 16, 2019
@divega
Copy link
Contributor Author

divega commented Apr 16, 2019

@roji @khellang is the discussion to have in triage about the feature represented by this issue (enabling composability for SQL queries that require a preamble) or about not bothering trying to tell composable from non-composaable SQL. I see both as largely separate. Also I remember vaguely that @smitpatel was already tracking the latter somewhere else.

@roji
Copy link
Member

roji commented Apr 17, 2019

@divega I think it's about the latter - removing any attempt to parse SQL and to identify composable vs. non-composable SQL. I took a quick look but couldn't find an issue tracking this - @smitpatel unless you have one I missed, I can open a new one.

@smitpatel
Copy link
Member

  • There is no tracking issue.
  • It is fixed since in the absence of client eval we are not going to verify if we have to do client composition.

I am fine either way - tracking issue or not.

@roji
Copy link
Member

roji commented Apr 17, 2019

OK, so I propose to close this issue and open another one tracking the removal of the composability check. Does that sound OK @divega @ajcvickers?

@smitpatel
Copy link
Member

@roji - negative. Even if the composability check is removed, AFAIK the functionality being talked about in this issue is still not possible. Without the check, we will just put it inside subquery when being composed over. And I am not sure WITH inside a subquery works.

@roji
Copy link
Member

roji commented Apr 17, 2019

Ah, I think I understand now (after reading this again) - sorry for the confusion. Returning to the backlog.

Am not sure that an issue for removing the SQL composability checks is needed, but opened #15392 to track that.

@smitpatel
Copy link
Member

@roji - Thank you for contributing to my bucket of 3.0 issues. :trollface:

@roji
Copy link
Member

roji commented Apr 17, 2019

Always a pleasure :trollface: :trollface: :trollface:

Although this one seems simple enough that I could do it too..

@divega
Copy link
Contributor Author

divega commented Apr 17, 2019

At least we can close #15392 as fixed, presumably 😄

@ajcvickers ajcvickers added this to the Backlog milestone Apr 19, 2019
@sdanyliv
Copy link

sdanyliv commented Apr 22, 2019

Maybe this documentation can help you in designing CTE API, it already works in production.
https://linq2db.github.io/articles/sql/CTE.html
I'm not a big expert in relinq, but I hope it is doable.

Also there can be more than one CTE in query, and they need to be properly ordered by topological sort, so just adding additional FromSql implementation may introduce new bugs after query optimization.

@divega divega added good first issue This issue should be relatively straightforward to fix. help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. and removed help wanted This issue involves technologies where we are not experts. Expert help would be appreciated. labels May 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants