Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizing pointer CLP query decoration done by DatabaseController#addPointerPermissions #6747

Merged

Conversation

mess-lelouch
Copy link
Contributor

@mess-lelouch mess-lelouch commented Jun 24, 2020

This change implements what was suggested in the following issue: #6708 (comment)

Basically, the code added looks for the type of the CLP pointers and decorates the query accordingly if the field is of type Pointer or Array. Also, it only introduces an $or query if there are multiple CLP pointer entries.

Below is the explain output of a simple find query when only a pointer CLP entry user is present

    "parsedQuery": {
      "$and": [
        {
          "_p_user": {
            "$eq": "_User$Qve7aWMSZo"
          }
        },
        {
          "_rperm": {
            "$in": [
              null,
              "*",
              "Qve7aWMSZo"
            ]
          }
        }
      ]
    },

Below is the explain output of a simple find query when only an array CLP entry users is present

    "parsedQuery": {
      "$and": [
        {
          "users": {
            "$eq": {
              "__type": "Pointer",
              "className": "_User",
              "objectId": "Qve7aWMSZo"
            }
          }
        },
        {
          "_rperm": {
            "$in": [
              null,
              "*",
              "Qve7aWMSZo"
            ]
          }
        }
      ]
    },

Below is the explain output of a simple find query when pointer/array CLP entries user/users are present

    "parsedQuery": {
      "$and": [
        {
          "$or": [
            {
              "_p_user": {
                "$eq": "_User$Qve7aWMSZo"
              }
            },
            {
              "users": {
                "$eq": {
                  "__type": "Pointer",
                  "className": "_User",
                  "objectId": "Qve7aWMSZo"
                }
              }
            }
          ]
        },
        {
          "_rperm": {
            "$in": [
              null,
              "*",
              "Qve7aWMSZo"
            ]
          }
        }
      ]
    },

Please feel free to share any questions, concerns or observations that would help me improve this PR.

};
const ors = permFields.map((key) => {
const fieldDescriptor = schema.getExpectedType(className, key);
const fieldType = fieldDescriptor.type;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CI tests failed because I can get null/undefined/string in fieldDescriptor. Basically I assumed that I could only get a descriptor with a type of Array or Pointer, but it seems this is not the case. I will investigate this issue further and revisit this code. If anyone can point me in the right direction as to why I can get null/undefined or a string as the pointer CLP I will appreciate it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I realized that the CI build failed because of the flow type checker and I know why. I am still getting used to flow since I haven't used it before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it.

@mess-lelouch
Copy link
Contributor Author

I just added some tests...

@codecov
Copy link

codecov bot commented Jun 24, 2020

Codecov Report

Merging #6747 into master will decrease coverage by 0.07%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6747      +/-   ##
==========================================
- Coverage   93.90%   93.83%   -0.08%     
==========================================
  Files         169      169              
  Lines       12197    12267      +70     
==========================================
+ Hits        11454    11511      +57     
- Misses        743      756      +13     
Impacted Files Coverage Δ
src/Controllers/DatabaseController.js 95.33% <100.00%> (+0.05%) ⬆️
src/GraphQL/loaders/usersMutations.js 91.73% <0.00%> (-1.51%) ⬇️
src/GraphQL/loaders/usersQueries.js 96.42% <0.00%> (-1.08%) ⬇️
src/Adapters/Storage/Mongo/MongoStorageAdapter.js 92.87% <0.00%> (-0.67%) ⬇️
...dapters/Storage/Postgres/PostgresStorageAdapter.js 96.02% <0.00%> (-0.32%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ea1ec9b...01d1812. Read the comment docs.

@mess-lelouch
Copy link
Contributor Author

I am going to ignore the code coverage errors for now. It was not failing until my last push to the branch, which added tests to cover areas that weren't previously covered. It did not failed when I originally created the PR.

@mess-lelouch
Copy link
Contributor Author

@mtrezza I apologize in advance for tagging you. I do have one question to ask and I didn't know where to ask.

What actions do I need to take to get this work reviewed? Asking since this PR has been up for a while and I do not know if I need to take some additional actions so that my work starts to get reviewed.

If I just need to wait for a maintainer to review my work, then I do not mind the wait :)

Thanks in advance!

@mtrezza
Copy link
Member

mtrezza commented Jul 7, 2020

@mess-lelouch Thanks for your contribution and apologies for the wait. I remember the analysis of this issue this PR intends to fix. Let me look into this again in some more detail. In the mean time, can you please make sure (if you haven't already) that we have a test case for every possible scenario:

  • pointer: _User$...
  • literal pointer object: {"__type": "Pointer", ... }
  • single / multiple pointers references (?)
  • ...?

Also, can you please make sure there are no (lint) changes in the PR of unrelated code, so we can focus on the actual change.

@mess-lelouch
Copy link
Contributor Author

mess-lelouch commented Jul 7, 2020

@mess-lelouch Thanks for your contribution and apologies for the wait. I remember the analysis of this issue this PR intends to fix. Let me look into this again in some more detail. In the mean time, can you please make sure (if you haven't already) that we have a test case for every possible scenario:

  • pointer: _User$...
  • literal pointer object: {"__type": "Pointer", ... }
  • single / multiple pointers references (?)
  • ...?

Also, can you please make sure there are no (lint) changes in the PR of unrelated code, so we can focus on the actual change.

No need to apologize. On the contrary, thank you for dedicating your time to maintaining this piece of software that I use.

I added test cases for everything you mentioned except for the literal object case. And the reason I didn't is because I assumed it was not supported since the dashboard does not let me set a field of type Object in the CLP. It only lets me set user pointers and (as of recently) arrays.

That said, I could easily add it if you think it is necessary (i.e. due to backwards compatibility reasons).

@mtrezza
Copy link
Member

mtrezza commented Jul 7, 2020

That said, I could easily add it if you think it is necessary (i.e. due to backwards compatibility reasons).

Exactly because of that - IIRC I made an assumption as to why literal pointer objects are supported, but there was no definitive conclusion, so to be safe I suggest we add this for backwards compatibility and add a code comment for future contributors, so we may remove that code at some point in the future. Unless you want to do some more research regarding this to remove this on more solid ground.

@mess-lelouch
Copy link
Contributor Author

That said, I could easily add it if you think it is necessary (i.e. due to backwards compatibility reasons).

Exactly because of that - IIRC I made an assumption as to why literal pointer objects are supported, but there was no definitive conclusion, so to be safe I suggest we add this for backwards compatibility and add a code comment for future contributors, so we may remove that code at some point in the future. Unless you want to do some more research regarding this to remove this on more solid ground.

Makes sense... I think I will save myself some time and add it.

@mess-lelouch
Copy link
Contributor Author

@mtrezza ok, I think that with my latest changes I now handle the Object case properly. I updated the tests as well.

Copy link
Member

@dplewis dplewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! @BufferUnderflower Can you look this over?

@dplewis dplewis requested review from davimacedo and mtrezza July 17, 2020 14:33
Copy link
Member

@davimacedo davimacedo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good to me.

@dplewis
Copy link
Member

dplewis commented Jul 17, 2020

Travis didn't rerun, I'll close and reopen.

@dplewis dplewis closed this Jul 17, 2020
@dplewis dplewis reopened this Jul 17, 2020
@dplewis dplewis merged commit d698333 into parse-community:master Jul 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants