Skip to content

No running through SubQueries #69

@cinifyetr

Description

@cinifyetr

I have the problem that with SubQueries, the traversing stops.

var ast = new Parser().ParseSql(sql, new PostgreSqlDialect(), new ParserOptions()
{
    RecursionLimit = 20000
});
var visitor = new PostgresVisitor(allowedType);

ast.Visit(visitor);

Here an example sql query:

SELECT * 
FROM ds_customers c
LEFT JOIN LATERAL (
    SELECT *
    FROM ds_orders o
    WHERE o.customer_id = c.id
    ORDER BY o.order_date DESC
    LIMIT 3
) recent_orders ON true;

I am trying to collect all the tables called up. I have built a hotfix that checks if there is a SubQuery and runs it again. I can use it for reading. I also have a “ReplaceVisitor” which replaces table names. I can't get that to work. It would be great if the SubQuery could simply continue to be used normally like the main query. Am I doing something wrong here?

public override ControlFlow PreVisitTableFactor(TableFactor relation)
{
    // Handle TableFactor.Derived (for LATERAL JOINs and subqueries)
    if (relation is TableFactor.Derived derived)
    {
        Console.WriteLine($"[VISITOR] Found TableFactor.Derived - Lateral: {derived.Lateral}");
        if (derived.SubQuery != null)
        {
            Console.WriteLine($"[VISITOR] Derived has SubQuery - will let base visitor handle it");
            Console.WriteLine($"[VISITOR] SubQuery type: {derived.SubQuery.GetType().Name}");
            Console.WriteLine($"[VISITOR] SubQuery sql: {derived.SubQuery.ToSql()}");
            PostgresVisitor visitor = new PostgresVisitor(AllowedType);
            var ast = new Parser().ParseSql(derived.SubQuery.ToSql(), new PostgreSqlDialect(), new ParserOptions()
            {
              RecursionLimit = 20000
            });
            ast.Visit(this);
            return ControlFlow.Continue;
        }
        // Let the base visitor handle the traversal
        return base.PreVisitTableFactor(relation);
    }
    
    if (!(relation is TableFactor.Table))
        return base.PreVisitTableFactor(relation);

    var table = relation.AsTable();
    Console.WriteLine($"[VISITOR] Found TableFactor.Table - Name: {table?.Name}");

    if (table != null)
    {
        // logic for table
    }

    return base.PreVisitTableFactor(relation);
}

Without the derived.SubQuery part, the SubQuery is never run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions