Skip to content

Relation constraints on compound query do not work #7828

Description

@ricmatsui

New Issue Checklist

Issue Description

Adding relation constraints to a compound query for example: Query.or(...).equalTo('relationField', ...) does not work and no results are returned. This is because reduceInRelation only reduces the relations in the child queries and not the parent query:

reduceInRelation(className: string, query: any, schema: any): Promise<any> {
// Search for an in-relation or equal-to-relation
// Make it sequential for now, not sure of paralleization side effects
if (query['$or']) {
const ors = query['$or'];
return Promise.all(
ors.map((aQuery, index) => {
return this.reduceInRelation(className, aQuery, schema).then(aQuery => {
query['$or'][index] = aQuery;
});
})
).then(() => {
return Promise.resolve(query);
});
}

A workaround is to add the constraint to each query passed to Query.or which does work (and the relation is queried multiple times):

Query.or(
    new Query(....)
        ...
        .equalTo('relationField', ...),
    new Query(....)
        ...
        .equalTo('relationField', ...),
)

Steps to reproduce

This is a test that demonstrates the issue with running a query like Query.or(...).equalTo('relationField', ...): ricmatsui@e978388

And this is a PR with the failing test: #7829

  • Create a child object
  • Create parent objects with relation to child object and add child object
  • Run a query:
Query
    .or(
        new Query('ParentObject').equalTo('x', 4),
        new Query('ParentObject').equalTo('x', 3),
    )
    .equalTo('toChilds', childObject)
    .find()

Actual Outcome

Test case fails, and no results are returned

Expected Outcome

Test case passes, and parent objects with the child object are returned

Environment

Server

  • Parse Server version: 4.10.6
  • Operating system: macOS 11.6.3
  • Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): Local

Database

  • System (MongoDB or Postgres): MongoDB
  • Database version: 4.0.4
  • Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc): Local

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): JavaScript
  • SDK version: 3.3.0

Logs

Logs from test case
verbose: REQUEST for [POST] /1/batch: {
  "requests": [
    {
      "method": "POST",
      "body": {
        "x": 0
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 1
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 2
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 3
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 4
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 5
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 6
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 7
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 8
      },
      "path": "/1/classes/ChildObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 9
      },
      "path": "/1/classes/ChildObject"
    }
  ]
} {"body":{"requests":[{"body":{"x":0},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":1},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":2},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":3},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":4},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":5},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":6},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":7},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":8},"method":"POST","path":"/1/classes/ChildObject"},{"body":{"x":9},"method":"POST","path":"/1/classes/ChildObject"}]},"headers":{"accept":"*/*","connection":"close","content-length":"796","content-type":"text/plain","host":"localhost:8378","user-agent":"node-XMLHttpRequest, Parse/js3.4.1 (NodeJS 12.22.1)"},"method":"POST","url":"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/1/batch"}
verbose: RESPONSE from [POST] /1/batch: {
  "response": [
    {
      "success": {
        "objectId": "etq6bi5dbB",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "WTQcVsCwcU",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "Yxrro6kHiZ",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "PP8ZirxK13",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "Mf7Rpb8Knh",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "sFDTc7Poh0",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "VQvcczT3cw",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "6lec9srt6o",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "uTYmvCTM4y",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    },
    {
      "success": {
        "objectId": "g3uGpa0W8k",
        "createdAt": "2022-02-26T23:21:21.873Z"
      }
    }
  ]
} {"result":{"response":[{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"etq6bi5dbB"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"WTQcVsCwcU"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"Yxrro6kHiZ"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"PP8ZirxK13"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"Mf7Rpb8Knh"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"sFDTc7Poh0"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"VQvcczT3cw"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"6lec9srt6o"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"uTYmvCTM4y"}},{"success":{"createdAt":"2022-02-26T23:21:21.873Z","objectId":"g3uGpa0W8k"}}]}}
verbose: REQUEST for [POST] /1/batch: {
  "requests": [
    {
      "method": "POST",
      "body": {
        "x": 4,
        "toChilds": {
          "__op": "AddRelation",
          "objects": [
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "etq6bi5dbB"
            },
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "WTQcVsCwcU"
            },
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "Yxrro6kHiZ"
            }
          ]
        }
      },
      "path": "/1/classes/ParentObject"
    },
    {
      "method": "POST",
      "body": {
        "x": 3,
        "toChilds": {
          "__op": "AddRelation",
          "objects": [
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "etq6bi5dbB"
            },
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "WTQcVsCwcU"
            },
            {
              "__type": "Pointer",
              "className": "ChildObject",
              "objectId": "Yxrro6kHiZ"
            }
          ]
        }
      },
      "path": "/1/classes/ParentObject"
    },
    {
      "method": "POST",
      "body": {},
      "path": "/1/classes/ParentObject"
    }
  ]
} {"body":{"requests":[{"body":{"toChilds":{"__op":"AddRelation","objects":[{"__type":"Pointer","className":"ChildObject","objectId":"etq6bi5dbB"},{"__type":"Pointer","className":"ChildObject","objectId":"WTQcVsCwcU"},{"__type":"Pointer","className":"ChildObject","objectId":"Yxrro6kHiZ"}]},"x":4},"method":"POST","path":"/1/classes/ParentObject"},{"body":{"toChilds":{"__op":"AddRelation","objects":[{"__type":"Pointer","className":"ChildObject","objectId":"etq6bi5dbB"},{"__type":"Pointer","className":"ChildObject","objectId":"WTQcVsCwcU"},{"__type":"Pointer","className":"ChildObject","objectId":"Yxrro6kHiZ"}]},"x":3},"method":"POST","path":"/1/classes/ParentObject"},{"body":{},"method":"POST","path":"/1/classes/ParentObject"}]},"headers":{"accept":"*/*","connection":"close","content-length":"857","content-type":"text/plain","host":"localhost:8378","user-agent":"node-XMLHttpRequest, Parse/js3.4.1 (NodeJS 12.22.1)"},"method":"POST","url":"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/1/batch"}
verbose: RESPONSE from [POST] /1/batch: {
  "response": [
    {
      "success": {
        "objectId": "ksTc4ujnC0",
        "createdAt": "2022-02-26T23:21:21.897Z"
      }
    },
    {
      "success": {
        "objectId": "4YbB7WFIS0",
        "createdAt": "2022-02-26T23:21:21.897Z"
      }
    },
    {
      "success": {
        "objectId": "gPocYDntCQ",
        "createdAt": "2022-02-26T23:21:21.897Z"
      }
    }
  ]
} {"result":{"response":[{"success":{"createdAt":"2022-02-26T23:21:21.897Z","objectId":"ksTc4ujnC0"}},{"success":{"createdAt":"2022-02-26T23:21:21.897Z","objectId":"4YbB7WFIS0"}},{"success":{"createdAt":"2022-02-26T23:21:21.897Z","objectId":"gPocYDntCQ"}}]}}
verbose: REQUEST for [GET] /1/classes/ParentObject: {
  "where": {
    "$or": [
      {
        "x": 4
      },
      {
        "x": 3
      }
    ],
    "toChilds": {
      "__type": "Pointer",
      "className": "ChildObject",
      "objectId": "Yxrro6kHiZ"
    }
  }
} {"body":{"where":{"$or":[{"x":4},{"x":3}],"toChilds":{"__type":"Pointer","className":"ChildObject","objectId":"Yxrro6kHiZ"}}},"headers":{"accept":"*/*","connection":"close","content-length":"265","content-type":"text/plain","host":"localhost:8378","user-agent":"node-XMLHttpRequest, Parse/js3.4.1 (NodeJS 12.22.1)"},"method":"GET","url":"/1/classes/ParentObject"}
verbose: RESPONSE from [GET] /1/classes/ParentObject: {
  "response": {
    "results": []
  }
} {"result":{"response":{"results":[]}}}
F    ✗ or queries with base constraint on relation field
      - Expected -1 not to be -1.
      - Expected -1 not to be -1.
      - Expected 0 to equal 2.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions