edgedb icon indicating copy to clipboard operation
edgedb copied to clipboard

Performance falls apart when `or`ing two otherwise cheap filters

Open jackfischer opened this issue 1 year ago • 0 comments

  • EdgeDB Version: 4.8
  • EdgeDB CLI Version: 5.2.3
  • OS Version:

Steps to Reproduce:

  1. Query with two filters global current_user_object in .collaborators.collaborator global current_user_object.isAdminOfOwnOrg, both very fast
  2. Or the filters into (global current_user_object in .collaborators.collaborator) or (global current_user_object.isAdminOfOwnOrg) and performance blows up 100x (obviously data dependent)

Extended analyzes: cheapadmin.txt cheapcollaborators.txt expensive.txt

Schema:

using future nonrecursive_access_policies;

module default {

    global current_user: uuid;
    global current_user_object := (
        select User filter .id = global current_user
    );

    type Organization {
        multi link admins: User;

        access policy allow_select_users
            allow select
            using (global current_user_object.organization.id ?= .id);

        access policy allow_all_admin
            allow all
            using ((global current_user in .admins.id) ?? false);
    }

    abstract type Principal {
    }

    type Collaborator {
        required single link collaborator: User;
        required property `role`: CollaborationRole;
    }

    type Collection {
        required link organization: Organization;

        multi link collaborators: Collaborator {
            on target delete allow;
        }

        access policy editors_allow_all
            allow all
            using ((global current_user_object in (select .collaborators filter .role = <CollaborationRole>"editor").collaborator) ?? false);

        access policy everyone_allow_select
            allow select
            using ((global current_user_object.organization = .organization) ?? false);

        access policy admins_allow_all
            allow all
            using ((global current_user in .organization.admins.id) ?? false);

        access policy deny_if_user_not_in_appropriate_organization
            deny all
            using ((global current_user_object.organization != .organization) ?? true);
    }

    type User extending Principal {
        required link organization: Organization;
        required property isAdminOfOwnOrg := (
            .id in .organization.admins.id
        );
    }
}

jackfischer avatar Aug 21 '24 15:08 jackfischer