Query `containsAllStartingWith` returns wrong results with Postgres when the number of matching array elements differs from the number of prefixes

Ouverte Adaptée aux débutants
#10,871 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
84/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
javascript, postgresql
Domaine
backend, database

Piste de recherche

Commence par src/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql et compare sa logique de correspondance avec la sémantique de MongoDB décrite dans l’issue. Repère ensuite le spec existant containsAllStartingWith single regex value should return corresponding matching results et vérifie les cas où plusieurs éléments du tableau correspondent à un préfixe ou où un élément correspond à plusieurs préfixes. Le travail est terminé lorsque Postgres donne les mêmes résultats que MongoDB pour les trois exemples de l’issue.

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

Description

New Issue Checklist
Issue Description

With the Postgres adapter, containsAllStartingWith (REST: $all with ^\Q...\E prefix regexes on an Array field) is implemented by the SQL helper array_contains_all_regex in src/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql. The helper counts the array elements that match any of the patterns and compares that count with the number of patterns:

SELECT RES.CNT = jsonb_array_length("values")
FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt
      WHERE elt LIKE ANY (SELECT jsonb_array_elements_text("values"))) as RES

This is not the semantics of the operator on MongoDB ($all: [/^\Qa\E/, ...]: every pattern must match at least one element). The count comparison gives wrong results whenever the number of matching elements differs from the number of patterns:

  1. False negative when more elements match than patterns were given: ['aaa', 'ab'] with prefix a → 2 matching elements ≠ 1 pattern → false.
  2. False negative when one element satisfies several patterns: ['aaa'] with prefixes a and aa → 1 ≠ 2 → false.
  3. False positive when several elements match one pattern while another pattern matches nothing: ['aaa', 'abb'] with prefixes a and b → 2 = 2 → true, although no element starts with b.

MongoDB returns the opposite result in all three cases. The existing spec containsAllStartingWith single regex value should return corresponding matching results passes on Postgres only because its test data has exactly one matching element per object.

Steps to reproduce
const object = new Parse.Object('TestObject');
object.set('strings', ['aaa', 'ab']);
await object.save();

const query = new Parse.Query('TestObject');
query.containsAllStartingWith('strings', ['a']);
const results = await query.find();

REST equivalent: where={"strings":{"$all":[{"$regex":"^\\Qa\\E"}]}}.

SQL-level check against the test database (the helper is created by the adapter):

SELECT array_contains_all_regex('["aaa","ab"]'::jsonb, '["a%"]'::jsonb);       -- false, expected true
SELECT array_contains_all_regex('["aaa"]'::jsonb, '["a%","aa%"]'::jsonb);      -- false, expected true
SELECT array_contains_all_regex('["aaa","abb"]'::jsonb, '["a%","b%"]'::jsonb); -- true, expected false
Actual Outcome

Postgres: the query in the example returns no results; MongoDB returns the object. The SQL helper returns the values noted in the comments above.

Expected Outcome

The same results as MongoDB: an object matches when every prefix matches at least one array element, independent of how many elements match. For example, count the patterns that have at least one matching element and compare that count with the number of patterns.

Environment

Server

  • Parse Server version: 9.11.1-alpha.2
  • Operating system: macOS 27.0.1
  • Local or remote host: local

Database

  • System (MongoDB or Postgres): Postgres
  • Database version: PostgreSQL 16 with PostGIS 3.5 (postgis/postgis:16-3.5)
  • Local or remote host: local Docker

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): JavaScript / REST
  • SDK version: 8.7.0
Logs

n/a

Langage dominant
JavaScript
Étoiles
21.4k
Forks
4.8k
Merge moyen
7 h 8 min
PR mergées (30 j)
65

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de parse-community/parse-server

Toutes les issues de parse-community/parse-server

Issues similaires

Plus d'issues JavaScript

Recevez les nouvelles issues par e-mail

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