Skip to content

Syntax error in findCount with Formula join + DISTINCT ON + inner ORDER BY #3686

@JrDuComptoirDesPharmacies

Description

Description

When a property annotated with @formula uses a join and the outer query runs findCount over a DISTINCT ON subquery that includes an inner ORDER BY, Ebean generates an invalid count subquery that is missing a closing parenthesis before the subselect alias, causing a PostgreSQL syntax error.

Minimal model

@Entity
class Ad extends Model {
   @Id
   @GeneratedValue
   public Long id;

  @Transient
  @Formula(
    select = "${ta}.discounted_price",
    join = "LEFT JOIN price_range ON price_range.ad_id = ${ta}.id"
  )
  private BigDecimal discounted_price;

  @Column(precision = 8, scale = 2)
  private BigDecimal rebate;
}

Ebean query:

DB.find(models.Ad.class)
        .where()
        .in("id",
                DB.find(models.Ad.class)
                        .select("id")
                        .distinctOn("rebate")
                        .where()
                        .orderBy("rebate")
                        .query()
        )
        .orderBy("discounted_price")
        .findCount();

Generated queries

Working findList case, generated SQL:
select t0.id, t0.rebate from ad t0 LEFT JOIN price_range ON price_range.ad_id = t0.id where t0.id in (select distinct on (t0.rebate) t0.id from ad t0 order by t0.rebate) order by t0.discounted_price;

Failing findCount:

Generated SQL (missing closing parenthesis before alias):

Query threw SQLException:ERROR: syntax error at or near "as"
  Position : 164 Bind values:[] Query was:select count(*) from ( select t0.id from ad t0 LEFT JOIN price_range ON price_range.ad_id = t0.id where t0.id in (select distinct on (t0.rebate) t0.id from ad t0) as c

Removing the inner orderBy from the DISTINCT ON subquery makes findCount succeed again:

DB.find(models.Ad.class)
        .where()
        .in("id",
                DB.find(models.Ad.class)
                        .select("id")
                        .distinctOn("rebate")
                        .where()
//                        .orderBy("rebate")
                        .query()
        )
        .orderBy("discounted_price")
        .findCount();

Generated SQL:

select count(*) from ( select t0.id from ad t0 LEFT JOIN price_range ON price_range.ad_id = t0.id where t0.id in (select distinct on (t0.rebate) t0.id from ad t0) ) as c;

Steps to reproduce:

  1. Define the entity above with @formula and join.
  2. Run a query that uses in() over a subquery with distinctOn() and an inner orderBy, then call findCount() on the outer query.
  3. Observe the syntax error due to a missing closing parenthesis before the subselect alias in the generated count query.

Environment
ORM: Ebean 17.0.1
Database: PostgreSQL 16

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions