parse-community / parse-server

Parse Server for Node.js / Express
https://parseplatform.org
Apache License 2.0
20.92k stars 4.78k forks source link

Pointer queries under PostGres failing to return any results #7754

Closed PopeNobody closed 2 years ago

PopeNobody commented 2 years ago

New Issue Checklist

Issue Description

The following query returns no results under postgres, though there are several objects that should be returned.

The class in question is "PublicCell". Each PublicCell has an owner, who is a user. However, the following query does not return any results, even though the user I am using owns four cells.

  const ownerQ = new Parse.Query("PublicCell");
  ownerQ.equalTo("owner",user);
  console.log(ownerQ);
  const owned = await ownerQ.find();

  console.log("owned");
  for(var i=0;i<owned.length;i++){
    const cell = owned[i];
    console.log("  "+cell.get("name"));
  };
  console.log("");

The class is created with the following code:

export async function createPublicCellTable() {
  console.log("createPublicCellTable");
  const schema1 = new Parse.Schema("PublicCell");
  schema1.addPointer("owner","_User",{required: true});
  schema1.addString("name",{required: true});
  // This is inexact, and unchanging.  It is their hometown,
  // not their current location.  Generally, it should be
  // some business near where they congregate
  schema1.addGeoPoint("location",{required:true});
  schema1.addRelation("members","_User");
  schema1.addString("description",{required:true});
  schema1.addString("category",{required:true});
  schema1.addBoolean("verified",{required:true,defaultValue:false});
  schema1.save();
  console.log("createPublicCellTable done");
};

The "members" relation works fine. This query returns the cells of which the user in question is a member.

  joinedQ.equalTo("members", user);
  console.log(joinedQ);
  const joined = await joinedQ.find();

  console.log("joined");
  for(var i=0;i<joined.length;i++){
    const cell = joined[i];
    console.log("  "+cell.get("name"));
  };
  console.log("");

Steps to reproduce

Create the class above, create an instance which is owned by your user, and the query for instances of PublicCell which are owned by your user.

Actual Outcome

I got nothing back.

Expected Outcome

I expected to get my objects.

Environment

Server

Database

Client

Logs

Ok, having answered the questions, I seem to have the fix. It works for me for the queries I am trying to do, though it might break other stuff.

diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
index f787d9f1..c72f471e 100644
--- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
+++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
@@ -729,7 +729,8 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
         values.push(fieldName, JSON.stringify([fieldValue]));
         index += 2;
       } else {
-        patterns.push(`$${index}:name = $${index + 1}`);
+        patterns.push(`($${index}:name)::json->>'objectId' = $${index + 1}::text`);
+        //patterns.push(`$${index}:name = $${index + 1}`);
         values.push(fieldName, fieldValue.objectId);
         index += 2;
       }

The old code was comparing (something ... I don't really grok the :name syntax .. I assume it was the full pointer JSON object ) to fieldValue.objectId. But the field is not an objectId, it's a Pointer. So I changed it to use the postgres "extract field as text from json" operator, and that made my shit work.

I have not tested all of the system with the patch. But what I am doing now works, and that is all I have time for at the moment.

As a special bonus, I have second patch for you:


diff --git a/src/ParseServer.js b/src/ParseServer.js
index e6b30d19..da6b7500 100644
--- a/src/ParseServer.js
+++ b/src/ParseServer.js
@@ -205,7 +205,7 @@ class ParseServer {
       // verify the server url after a 'mount' event is received
       /* istanbul ignore next */
       api.on('mount', function () {
-        ParseServer.verifyServerUrl();
+        setTimeout(ParseServer.verifyServerUrl, 1000);
       });
     }
     if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) {

There seems to be a race condition in the startup code which caused my server to emit the following warning on startup:

             `\nWARNING, Unable to connect to '${Parse.serverURL}'.` +
                ` Cloud code and push notifications may be unavailable!\n`

Using setTimeout to delay the test by one second resolves the issue.

I hope these patches are useful to you, and I declaim all ownership of them. Use them any way you like, with no expectation of recompens.

parse-github-assistant[bot] commented 2 years ago

Thanks for opening this issue!

PopeNobody commented 2 years ago

Sorry I didn't have time to go through the bug report process a second time for the second patch.

PopeNobody commented 2 years ago

It looks like my data was wrong. Sorry about that!

Things seem to have gone wrong when copying data from mongodb to postgres.

mtrezza commented 2 years ago

It looks like my data was wrong. Sorry about that!

Can we close this issue as false alarm?

PopeNobody commented 2 years ago

I'm afraid so. I am in the process of moving a parse installation from parse to mongo, and it appears that I was not getting any results because I had not munged the data properly. It was in the as a tripple, like you see of you do a console.log() of a fresh parse object, but it was supposed to be just the object id in the column. When I fixed the data, the problem stopped happening.

mtrezza commented 2 years ago

Great, thanks for clarifying, I'll go ahead and close.