fix: Avoid joining tables to fix the distinct value query (#7965)

DISTINCT query with custom attributes return an error. To avoid the error, this PR refactors the query to include tags only when it is required.

Fixes #7931
Fixes #7836

Co-authored-by: Sojan Jose <sojan@pepalo.com>
This commit is contained in:
Pranav Raj S
2023-09-22 19:48:56 -07:00
committed by GitHub
parent dd0930d75e
commit ff915dd2ea
4 changed files with 94 additions and 30 deletions

View File

@@ -35,7 +35,7 @@ class Contacts::FilterService < FilterService
" (contacts.#{attribute_key})::#{current_filter['data_type']} #{filter_operator_value}#{current_filter['data_type']} #{query_operator} "
when 'standard'
if attribute_key == 'labels'
" tags.id #{filter_operator_value} #{query_operator} "
tag_filter_query('Contact', 'contacts', query_hash, current_index)
else
" LOWER(contacts.#{attribute_key}) #{filter_operator_value} #{query_operator} "
end
@@ -54,7 +54,7 @@ class Contacts::FilterService < FilterService
end
def base_relation
Current.account.contacts.distinct(:id).left_outer_joins(:labels)
Current.account.contacts
end
private

View File

@@ -46,7 +46,7 @@ class Conversations::FilterService < FilterService
" (conversations.#{attribute_key})::#{current_filter['data_type']} #{filter_operator_value}#{current_filter['data_type']} #{query_operator} "
when 'standard'
if attribute_key == 'labels'
" tags.name #{filter_operator_value} #{query_operator} "
tag_filter_query('Conversation', 'conversations', query_hash, current_index)
else
" conversations.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
@@ -54,7 +54,9 @@ class Conversations::FilterService < FilterService
end
def base_relation
@account.conversations.left_outer_joins(:labels)
@account.conversations.includes(
:taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team, :messages, :contact_inbox
)
end
def current_page
@@ -62,10 +64,6 @@ class Conversations::FilterService < FilterService
end
def conversations
@conversations = @conversations.includes(
:taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team, :messages, :contact_inbox
)
@conversations.latest.page(current_page)
end
end

View File

@@ -106,6 +106,27 @@ class FilterService
]
end
def tag_filter_query(model_name, table_name, query_hash, current_index)
query_operator = query_hash[:query_operator]
@filter_values["value_#{current_index}"] = filter_values(query_hash)
tag_model_relation_query =
"SELECT * FROM taggings WHERE taggings.taggable_id = #{table_name}.id AND taggings.taggable_type = '#{model_name}'"
tag_query =
"AND taggings.tag_id IN (SELECT tags.id FROM tags WHERE tags.name IN (:value_#{current_index}))"
case query_hash[:filter_operator]
when 'equal_to'
"EXISTS (#{tag_model_relation_query} #{tag_query}) #{query_operator}"
when 'not_equal_to'
"NOT EXISTS (#{tag_model_relation_query} #{tag_query}) #{query_operator}"
when 'is_present'
"EXISTS (#{tag_model_relation_query}) #{query_operator}"
when 'is_not_present'
"NOT EXISTS (#{tag_model_relation_query}) #{query_operator}"
end
end
def custom_attribute_query(query_hash, custom_attribute_type, current_index)
@attribute_key = query_hash[:attribute_key]
@custom_attribute_type = custom_attribute_type