introproventures / graphql-jpa-query

Generate GraphQL Query Api for your JPA Entity Models
https://github.com/introproventures/graphql-jpa-query
Apache License 2.0
195 stars 54 forks source link

Skip redundant fetch query for empty query keys results #508

Closed igdianov closed 3 days ago

igdianov commented 3 days ago

Skip executing redundant paged fetch query that does not have any results, i.e.

query tasksWithMultipleProcessVariables {
  Tasks(page: {limit : {Int}, start : {Int}}, where: {status : {IN : [CREATED]}, AND : [{processVariables : {name : {EQ : {String}}, value : {EQ : {String}}}}, {name : {LIKE : {String}}}]}) {
    total
    pages
    select {
      id
      processInstanceId
      assignee
      status
      candidateGroups
      createdDate(orderBy: ASC)
      processVariables(where: {name : {IN : [{String}]}}) {
        name
        type
        value
      }
    }
  }
}

The first generated SQL query fetches task keys with the empty result, i.e.

select te1_0.id 
from task te1_0 
    left join task_process_variable pv1_0 on te1_0.id = pv1_0.task_id 
    left join process_variable pv1_1 on pv1_1.id = pv1_0.process_variable_id 
where pv1_1.name = ? and pv1_1. value = ? and te1_0.name like ? escape ? and te1_0.status in ( ? ) 
order by te1_0.created_date offset ? rows 
fetch first ? rows only

After that, the second fetch query does not apply in search criteria is when the list of ids from the id query is empty, which fetch all data without keys restrictions, i.e.

select distinct te1_0.id, te1_0.app_name, te1_0.app_version, te1_0.assignee, te1_0.business_key, te1_0.claimed_date, te1_0.completed_by, te1_0.completed_date, te1_0.completed_from, te1_0.completed_to, te1_0.created_date, te1_0.created_from, te1_0.created_to, te1_0.description, te1_0.due_date, te1_0.duration, te1_0.form_key, te1_0.last_claimed_from, te1_0.last_claimed_to, te1_0.last_modified, te1_0.last_modified_from, te1_0.last_modified_to, te1_0.name, te1_0.owner, te1_0.parent_task_id, te1_0.priority, te1_0.process_definition_id, te1_0.process_definition_name, te1_0.process_definition_version, te1_0.process_instance_id, pv1_0.task_id, pv1_1.id, pv1_1.app_name, pv1_1.app_version, pv1_1.create_time, pv1_1.execution_id, pv1_1.last_updated_time, pv1_1.marked_as_deleted, pv1_1.name, pv1_1.process_definition_key, pv1_1.process_instance_id, pv1_1.service_full_name, pv1_1.service_name, pv1_1.service_type, pv1_1.service_version, pv1_1.type, pv1_1.variable_definition_id, te1_0.service_full_name, te1_0.service_name, te1_0.service_type, te1_0.service_version, te1_0.status, te1_0.task_definition_key 
from task te1_0 
    left join task_process_variable pv1_0 on te1_0.id = pv1_0.task_id 
    left join process_variable pv1_1 on pv1_1.id = pv1_0.process_variable_id 
where pv1_1.name = ? and pv1_1. value = ? and te1_0.name like ? escape ? and te1_0.status in ( ? ) 
order by te1_0.created_date

This is a bug because, the second query should not need to execute at all if there are no ids found for the provided selection criteria. We also can skip total count if the select page result is empty to further improve query performance