Azure / Azure/data-api-builder

[Bug]: Hierarchical/relationship filtering works correctly in one direction but not in the other direction

Ouverte
#1,892 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug
Langage dominant
C#
Étoiles
1.5k
Forks
370
Merge moyen
3 j 22 h
PR mergées (30 j)
9

Description

### What happened?

Whereas the fix for [Issue 825](https://github.com/Azure/data-api-builder/issues/825) correctly addresses hierarchical/relationship filtering when the outer entity is on the *many* side of a one-to-many relationship, the inverse filtering behavior where the outer entity is on the *one* side of a one-to-many relationship seems incorrect.

The following GraphQL query pertaining to the T-SQL schema, data, and dab-config.json provided in [Issue 825](https://github.com/Azure/data-api-builder/issues/825) has the outer entity, *books*, as the *many* side and the inner entity, *series*, as the *one* side of the relationship.

```gql
{
books(filter: { and: [{title: {contains: "m"}}, { series: { id: { eq: 10001 }}}]}) {
items {
id
title
series {
id
name
}
}
}
}
```

Which yields:

```json
{
"data": {
"books": {
"items": [
{
"id": 1015,
"title": "Endymion",
"series": {
"id": 10001,
"name": "Hyperion Cantos"
}
},
{
"id": 1016,
"title": "The Rise of Endymion",
"series": {
"id": 10001,
"name": "Hyperion Cantos"
}
}
]
}
}
}
```

The foregoing query fetches a properly filtered response based on the conjunction of the two filter predicates.

However, if one inverts the query, with the outer entity, *series*, the *one* side of the relationship and the inner entity, *books*, the *many* side of the relationship:

```gql
{
series(filter: {and: [{id: {eq: 10001}}, {books: {title: {contains: "m"}}}]} ) {
items {
id
name
books {
items {
id
title
year
pages
}
}
}
}
}
```

The result is:

```json
{
"data": {
"series": {
"items": [
{
"id": 10001,
"name": "Hyperion Cantos",
"books": {
"items": [
{
"id": 1013,
"title": "Hyperion",
"year": 1989,
"pages": 482
},
{
"id": 1014,
"title": "The Fall of Hyperion",
"year": 1990,
"pages": 517
},
{
"id": 1015,
"title": "Endymion",
"year": 1996,
"pages": 441
},
{
"id": 1016,
"title": "The Rise of Endymion",
"year": 1997,
"pages": 579
}
]
}
}
]
}
}
}
```

This filtering behavior seems incorrect. The query returns all items in the *books* collection so long as at least one of the items satisfies the filtering predicate *(contains 'm')*. Should not this query instead return only those items that satisfy the predicate? If this behavior of the API is intended, then it strikes me as both unintuitive and contradictory to the promise of GraphQL to ["give clients the power to ask for exactly what they need and nothing more"](https://graphql.org/).

Of course, the intended filtered results can be obtained in one-shot if the query is crafted correctly (i.e., in one relationship direction and not its inverse). Nevertheless, this observation breaks down when querying multiple related tables where an interim table is related to two other tables on the one-side of a relationship with one of the tables and on the many side of a relationship with the other table in the query. In that situation, either multiple queries are required, or the query must be encapsulated in a stored procedure, or subsequent client-side filtering must be employed to properly filter the result set.

### Version

8.52

### What database are you using?

Azure SQL

### What hosting model are you using?

Local (including CLI)

### Which API approach are you accessing DAB through?

GraphQL

### Relevant log output

_No response_

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Commencez par reproduire la requête GraphQL inverse de filtrage des relations de cette issue en utilisant le schéma T-SQL, les données et dab-config.json de Issue 825 sur Azure SQL. Comparez les résultats one-to-many et many-to-one ; c’est terminé lorsque la requête des séries renvoie uniquement les livres dont les titres correspondent au filtre, tout en préservant les résultats de relations attendus.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
azure, csharp, graphql, sql
Domaine
api, backend-api-design, databases
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
30/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.