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

CteFinder currently does not support set operations #534

Open
mindcrash opened this issue Nov 1, 2021 · 1 comment
Open

CteFinder currently does not support set operations #534

mindcrash opened this issue Nov 1, 2021 · 1 comment

Comments

@mindcrash
Copy link

mindcrash commented Nov 1, 2021

When the right hand side of Union(), Intersect() or Except() contains Common Table Expressions these are not written because CteFinder currently has no support for traversing AbstractCombine nodes.

As I need this functionality right now, I patched the findInternal function in CteFinder as follows:

private List<AbstractFrom> findInternal(Query queryToSearch)
{
    var cteList = queryToSearch.GetComponents<AbstractFrom>("cte", engineCode);

    // Traverse the right hand side of Union, Intersect and Except operators, if any
    var combineClauses = queryToSearch.GetComponents<AbstractCombine>("combine", engineCode);

    foreach (var combineClause in combineClauses)
    {
        if (combineClause is Combine combine)
        {
            // Add common table expression nodes, if any
            cteList.AddRange(combine.Query.GetComponents<AbstractFrom>("cte", engineCode));
        }
    }
    
    var resultList = new List<AbstractFrom>();

    foreach (var cte in cteList)
    {
        if (namesOfPreviousCtes.Contains(cte.Alias))
            continue;

        namesOfPreviousCtes.Add(cte.Alias);
        resultList.Add(cte);

        if (cte is QueryFromClause queryFromClause)
        {
            resultList.InsertRange(0, findInternal(queryFromClause.Query));
        }
    }

    return resultList;
}
@mindcrash mindcrash changed the title CteFinder does not currently support set operations CteFinder currently does not support set operations Nov 1, 2021
@ashishoffline
Copy link

ashishoffline commented Oct 19, 2024

@mindcrash what you mean by I patched the findInternal function in CteFinder ?
You have made the change and published your version for your use case?

I am having same issue, but instead of publishing own, I am thinking of writing extension method like following and using this method over the built in

namespace SqlKata;

public static class SqlKataExtensions
{

    private const string CteComponentName = "cte";
    public static Query CustomIntersect(this Query query, Query intersectQuery)
    {
        if (intersectQuery.HasComponent(CteComponentName))
        {
            var allCTE = intersectQuery.GetComponents(CteComponentName);
            foreach (var item in allCTE)
            {
                query.AddComponent(item.Component, item, item.Engine);
            }

            intersectQuery.ClearComponent(CteComponentName);
        }

        query.Intersect(intersectQuery);

        return query;
    }

    public static Query CustomUnion(this Query query, Query unionQuery)
    {
        if (unionQuery.HasComponent(CteComponentName))
        {
            var allCTE = unionQuery.GetComponents(CteComponentName);
            foreach (var item in allCTE)
            {
                query.AddComponent(item.Component, item, item.Engine);
            }

            unionQuery.ClearComponent(CteComponentName);
        }

        query.Union(unionQuery);

        return query;
    }

    public static Query CustomExcept(this Query query, Query exceptQuery)
    {
        if (exceptQuery.HasComponent(CteComponentName))
        {
            var allCTE = exceptQuery.GetComponents(CteComponentName);
            foreach (var item in allCTE)
            {
                query.AddComponent(item.Component, item, item.Engine);
            }

            exceptQuery.ClearComponent(CteComponentName);
        }

        query.Except(exceptQuery);

        return query;
    }
}

@ahmad-moussawi is this not a correct expectation?
Any suggestion for the work-around mentioned above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants