simple-sql-parser icon indicating copy to clipboard operation
simple-sql-parser copied to clipboard

Bug: Brackets required in generated select statement.

Open hanjoosten opened this issue 5 months ago • 6 comments

I use this library to programmatically generate SQL. Recently, I am adding a feature in which I need to use recursive common table expressions. Fortunately, you support this with the With constructor of data type QueryExpr. However, if there are more than one elements in the qeViews list, the generated sql forgets to put brackets when used as subquery in a QueryExprSetOp.

Currently, the query is output as:

  select SrcA as src, TgtA as tgt
  from r
  where (SrcA = '_SRCATOM')
        and ((SrcA is not null)
             and (TgtA is not null))
  union distinct
  with recursive TheExpression as (/* EDcD r[A*A] */
                                   /*    Expression: r [A*A] */
                                   /*    Signature : [A*A] */
                                   select SrcA as src, TgtA as tgt
                                   from r
                                   where (SrcA is not null)
                                         and (TgtA is not null)),
       TransitiveClosure as (select src as src, tgt as tgt from TheExpression
                             union distinct
                             select TransitiveClosure.src as src,
                                    TheExpression.tgt as tgt
                             from TransitiveClosure,
                                  TheExpression
                             where TheExpression.src = TransitiveClosure.tgt)
  select src as src, tgt as tgt from TransitiveClosure where src = '_SRCATOM'
  ;

The brackets should be placed at the subquery that is the right hand side of the Union, like this:

  select SrcA as src, TgtA as tgt
  from r
  where (SrcA = '_SRCATOM')
        and ((SrcA is not null)
             and (TgtA is not null))
  union distinct
  ( with recursive TheExpression as (/* EDcD r[A*A] */
                                   /*    Expression: r [A*A] */
                                   /*    Signature : [A*A] */
                                   select SrcA as src, TgtA as tgt
                                   from r
                                   where (SrcA is not null)
                                         and (TgtA is not null)),
       TransitiveClosure as (select src as src, tgt as tgt from TheExpression
                             union distinct
                             select TransitiveClosure.src as src,
                                    TheExpression.tgt as tgt
                             from TransitiveClosure,
                                  TheExpression
                             where TheExpression.src = TransitiveClosure.tgt)
  select src as src, tgt as tgt from TransitiveClosure where src = '_SRCATOM'
  );

hanjoosten avatar Oct 01 '24 10:10 hanjoosten