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

Abierto Apto para principiantes
#10,871 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
84/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
javascript, postgresql
Área
backend, database

Línea de trabajo

Empieza por src/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql y compara su lógica de coincidencia con la semántica de MongoDB descrita en el issue. Después, localiza el spec existente containsAllStartingWith single regex value should return corresponding matching results y comprueba los casos en los que varios elementos del array coinciden con un prefijo o un elemento coincide con varios prefijos. Se considera terminado cuando Postgres coincide con MongoDB en los tres ejemplos del issue.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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

Lenguaje dominante
JavaScript
Estrellas
21.4k
Forks
4.8k
Merge medio
7 h 8 min
PR fusionados (30 d)
65

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de parse-community/parse-server

Todos los issues de parse-community/parse-server

Issues similares

Más issues de JavaScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.