graphql-engine/server/tests-py/queries/graphql_query/bigquery/offset_regression.yaml
Chris Done 614c0dab80 Bigquery/fix limit offset for array aggregates
Blocked on https://github.com/hasura/graphql-engine-mono/pull/1640.

While fiddling with BigQuery I noticed a severe issue with offset/limit for array-aggregates. I've fixed it now.

The basic problem was that I was using a query like this:

```graphql
query MyQuery {
  hasura_Artist(order_by: {artist_self_id: asc}) {
    artist_self_id
    albums_aggregate(order_by: {album_self_id: asc}, limit: 2) {
      nodes {
        album_self_id
      }
      aggregate {
        count
      }
    }
  }
}
```

Producing this SQL:

```sql
SELECT `t_Artist1`.`artist_self_id` AS `artist_self_id`,
       STRUCT(IFNULL(`aa_albums1`.`nodes`, NULL) AS `nodes`, IFNULL(`aa_albums1`.`aggregate`, STRUCT(0 AS `count`)) AS `aggregate`) AS `albums_aggregate`
FROM `hasura`.`Artist` AS `t_Artist1`
LEFT OUTER JOIN (SELECT ARRAY_AGG(STRUCT(`t_Album1`.`album_self_id` AS `album_self_id`) ORDER BY (`t_Album1`.`album_self_id`) ASC) AS `nodes`,
                        STRUCT(COUNT(*) AS `count`) AS `aggregate`,
                        `t_Album1`.`artist_other_id` AS `artist_other_id`
                 FROM (SELECT *
                       FROM `hasura`.`Album` AS `t_Album1`
                       ORDER BY (`t_Album1`.`album_self_id`) ASC NULLS FIRST
                       -- PROBLEM HERE
                       LIMIT @param0) AS `t_Album1`
                 GROUP BY `t_Album1`.`artist_other_id`)
AS `aa_albums1`
ON (`aa_albums1`.`artist_other_id` = `t_Artist1`.`artist_self_id`)
ORDER BY (`t_Artist1`.`artist_self_id`) ASC NULLS FIRST
```

Note the `LIMIT @param0` -- that is incorrect because we want to limit
per artist. Instead, we want:

```sql
SELECT `t_Artist1`.`artist_self_id` AS `artist_self_id`,
       STRUCT(IFNULL(`aa_albums1`.`nodes`, NULL) AS `nodes`, IFNULL(`aa_albums1`.`aggregate`, STRUCT(0 AS `count`)) AS `aggregate`) AS `albums_aggregate`
FROM `hasura`.`Artist` AS `t_Artist1`
LEFT OUTER JOIN (SELECT ARRAY_AGG(STRUCT(`t_Album1`.`album_self_id` AS `album_self_id`) ORDER BY (`t_Album1`.`album_self_id`) ASC) AS `nodes`,
                        STRUCT(COUNT(*) AS `count`) AS `aggregate`,
                        `t_Album1`.`artist_other_id` AS `artist_other_id`
                 FROM (SELECT *,
                            -- ADDED
                            ROW_NUMBER() OVER(PARTITION BY artist_other_id) artist_album_index
                       FROM `hasura`.`Album` AS `t_Album1`
                       ORDER BY (`t_Album1`.`album_self_id`) ASC NULLS FIRST
                       ) AS `t_Album1`
                 -- CHANGED
                 WHERE artist_album_index <= @param
                 GROUP BY `t_Album1`.`artist_other_id`)
AS `aa_albums1`
ON (`aa_albums1`.`artist_other_id` = `t_Artist1`.`artist_self_id`)
ORDER BY (`t_Artist1`.`artist_self_id`) ASC NULLS FIRST
```

That serves both the LIMIT/OFFSET function in the where clause. Then,
both the ARRAY_AGG and the COUNT are correct per artist.

I've updated my Haskell test suite to add regression tests for this. I'll push a commit for Python tests shortly. The tests still pass there.

This just fixes a case that we hadn't noticed.

https://github.com/hasura/graphql-engine-mono/pull/1641

GitOrigin-RevId: 49933fa5e09a9306c89565743ecccf2cb54eaa80
2021-07-06 08:29:39 +00:00

190 lines
4.4 KiB
YAML

- description: Aggregate with a limit using nodes, count
url: /v1/graphql
status: 200
response:
data:
hasura_Artist:
- artist_self_id: '1000'
albums_aggregate:
nodes:
- album_self_id: '2002'
aggregate:
count: '1'
- artist_self_id: '1001'
albums_aggregate:
nodes:
- album_self_id: '2000'
aggregate:
count: '1'
- artist_self_id: '1002'
albums_aggregate:
nodes:
- album_self_id: '2003'
aggregate:
count: '1'
query:
query: |
query MyQuery {
hasura_Artist(order_by: {artist_self_id: asc}) {
artist_self_id
albums_aggregate(order_by: {album_self_id: asc}, limit: 1) {
nodes {
album_self_id
}
aggregate {
count
}
}
}
}
- description: Aggregate with order by using nodes, count, sum
url: /v1/graphql
status: 200
response:
data:
hasura_Artist:
- artist_self_id: '1001'
albums_aggregate:
nodes:
- album_self_id: '2000'
- album_self_id: '2001'
aggregate:
count: '2'
sum:
album_self_id: '4001'
- artist_self_id: '1002'
albums_aggregate:
nodes:
- album_self_id: '2003'
- album_self_id: '2004'
aggregate:
count: '2'
sum:
album_self_id: '4007'
- artist_self_id: '1000'
albums_aggregate:
nodes:
- album_self_id: '2002'
- album_self_id: '2005'
aggregate:
count: '2'
sum:
album_self_id: '4007'
query:
query: |
query MyQuery {
hasura_Artist {
artist_self_id
albums_aggregate(order_by: {album_self_id: asc}) {
nodes {
album_self_id
}
aggregate {
count
sum {
album_self_id
}
}
}
}
}
- description: Aggregate with limit using sum, nodes
url: /v1/graphql
status: 200
response:
data:
hasura_Artist:
- artist_self_id: '1001'
albums_aggregate:
nodes:
- album_self_id: '2000'
aggregate:
count: '1'
sum:
album_self_id: '2000'
- artist_self_id: '1002'
albums_aggregate:
nodes:
- album_self_id: '2003'
aggregate:
count: '1'
sum:
album_self_id: '2003'
- artist_self_id: '1000'
albums_aggregate:
nodes:
- album_self_id: '2002'
aggregate:
count: '1'
sum:
album_self_id: '2002'
query:
query: |
query MyQuery {
hasura_Artist {
artist_self_id
albums_aggregate(order_by: {album_self_id: asc}, limit: 1) {
nodes {
album_self_id
}
aggregate {
count
sum {
album_self_id
}
}
}
}
}
- description: Aggregate with offset using sum, nodes
url: /v1/graphql
status: 200
response:
data:
hasura_Artist:
- artist_self_id: '1001'
albums_aggregate:
nodes:
- album_self_id: '2001'
aggregate:
count: '1'
sum:
album_self_id: '2001'
- artist_self_id: '1002'
albums_aggregate:
nodes:
- album_self_id: '2004'
aggregate:
count: '1'
sum:
album_self_id: '2004'
- artist_self_id: '1000'
albums_aggregate:
nodes:
- album_self_id: '2005'
aggregate:
count: '1'
sum:
album_self_id: '2005'
query:
query: |
query MyQuery {
hasura_Artist {
artist_self_id
albums_aggregate(order_by: {album_self_id: asc}, offset: 1) {
nodes {
album_self_id
}
aggregate {
count
sum {
album_self_id
}
}
}
}
}