rewrite or quote table name in find_by_sql
refs CNVS-21900 Change-Id: I1e5d46494d1d9bb8aaebad6f8b84795308d1aab1 Reviewed-on: https://gerrit.instructure.com/58567 Tested-by: Jenkins Reviewed-by: Rob Orton <rob@instructure.com> Product-Review: Cody Cutrer <cody@instructure.com> QA-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
parent
daef59589d
commit
d54c7f8d2d
|
@ -690,10 +690,10 @@ class Account < ActiveRecord::Base
|
|||
if ActiveRecord::Base.configurations[Rails.env]['adapter'] == 'postgresql'
|
||||
Account.find_by_sql([<<-SQL, self.id, limit.to_i, offset.to_i])
|
||||
WITH RECURSIVE t AS (
|
||||
SELECT * FROM accounts
|
||||
SELECT * FROM #{Account.quoted_table_name}
|
||||
WHERE parent_account_id = ? AND workflow_state <>'deleted'
|
||||
UNION
|
||||
SELECT accounts.* FROM accounts
|
||||
SELECT accounts.* FROM #{Account.quoted_table_name}
|
||||
INNER JOIN t ON accounts.parent_account_id = t.id
|
||||
WHERE accounts.workflow_state <>'deleted'
|
||||
)
|
||||
|
@ -714,10 +714,10 @@ class Account < ActiveRecord::Base
|
|||
if connection.adapter_name == 'PostgreSQL'
|
||||
sql = "
|
||||
WITH RECURSIVE t AS (
|
||||
SELECT id, parent_account_id FROM accounts
|
||||
SELECT id, parent_account_id FROM #{Account.quoted_table_name}
|
||||
WHERE parent_account_id = #{parent_account_id} AND workflow_state <> 'deleted'
|
||||
UNION
|
||||
SELECT accounts.id, accounts.parent_account_id FROM accounts
|
||||
SELECT accounts.id, accounts.parent_account_id FROM #{Account.quoted_table_name}
|
||||
INNER JOIN t ON accounts.parent_account_id = t.id
|
||||
WHERE accounts.workflow_state <> 'deleted'
|
||||
)
|
||||
|
|
|
@ -439,9 +439,9 @@ class ActiveRecord::Base
|
|||
sql << "SELECT NULL AS #{column} WHERE EXISTS(SELECT * FROM #{table_name} WHERE #{column} IS NULL) UNION ALL (" if options[:include_nil]
|
||||
sql << <<-SQL
|
||||
WITH RECURSIVE t AS (
|
||||
SELECT MIN(#{column}) AS #{column} FROM #{table_name}
|
||||
SELECT MIN(#{column}) AS #{column} FROM #{quoted_table_name}
|
||||
UNION ALL
|
||||
SELECT (SELECT MIN(#{column}) FROM #{table_name} WHERE #{column} > t.#{column})
|
||||
SELECT (SELECT MIN(#{column}) FROM #{quoted_table_name} WHERE #{column} > t.#{column})
|
||||
FROM t
|
||||
WHERE t.#{column} IS NOT NULL
|
||||
)
|
||||
|
|
|
@ -3,29 +3,27 @@ class EnsureSubmissionsForDiscussions < ActiveRecord::Migration
|
|||
# entries from graded topics where the poster is enrolled as a student in
|
||||
# the topic's assignment's course and there's no current submission for the
|
||||
# poster and that assignment, but only one entry per (topic, user) pair
|
||||
entries = DiscussionEntry.find_by_sql(<<-SQL)
|
||||
SELECT DISTINCT discussion_entries.discussion_topic_id, discussion_entries.user_id
|
||||
FROM discussion_topics
|
||||
INNER JOIN assignments ON
|
||||
entries = DiscussionTopic.select(["discussion_entries.discussion_topic_id", "discussion_entries.user_id"]).
|
||||
uniq.
|
||||
joins("
|
||||
INNER JOIN #{Assignment.quoted_table_name} ON
|
||||
assignments.id=discussion_topics.assignment_id AND
|
||||
assignments.context_type='Course' AND
|
||||
assignments.submission_types='discussion_topic'
|
||||
INNER JOIN discussion_entries ON
|
||||
INNER JOIN #{DiscussionEntry.quoted_table_name} ON
|
||||
discussion_entries.discussion_topic_id=discussion_topics.id AND
|
||||
discussion_entries.workflow_state!='deleted'
|
||||
INNER JOIN enrollments ON
|
||||
INNER JOIN #{Enrollment.quoted_table_name} ON
|
||||
enrollments.course_id=assignments.context_id AND
|
||||
enrollments.user_id=discussion_entries.user_id AND
|
||||
enrollments.type='StudentEnrollment' AND
|
||||
enrollments.workflow_state NOT IN ('deleted', 'completed', 'rejected', 'inactive')
|
||||
LEFT JOIN submissions ON
|
||||
LEFT JOIN #{Submission.quoted_table_name} ON
|
||||
submissions.assignment_id=assignments.id AND
|
||||
submissions.user_id=discussion_entries.user_id AND
|
||||
submissions.submission_type='discussion_topic'
|
||||
WHERE
|
||||
discussion_topics.workflow_state='active' AND
|
||||
submissions.id IS NULL
|
||||
SQL
|
||||
submissions.submission_type='discussion_topic'").
|
||||
where(discussion_topics: { workflow_state: 'active' },
|
||||
submissions: { id: nil })
|
||||
|
||||
touched_course_ids = [].to_set
|
||||
touched_user_ids = [].to_set
|
||||
|
@ -34,30 +32,25 @@ class EnsureSubmissionsForDiscussions < ActiveRecord::Migration
|
|||
Submission.suspend_callbacks(:touch_user) do
|
||||
entries.each do |entry|
|
||||
# streamlined entry.discussiont_topic.ensure_submission(entry.user)
|
||||
assignment = Assignment.find_by_sql(<<-SQL).first
|
||||
SELECT assignments.id, assignments.group_category_id, assignments.context_id
|
||||
FROM assignments
|
||||
INNER JOIN discussion_topics ON
|
||||
assignment = Assignment.select(["assignments.id", :group_category_id, "assignments.context_id"]).
|
||||
joins("INNER JOIN #{DiscussionTopic.quoted_table_name} ON
|
||||
discussion_topics.assignment_id=assignments.id AND
|
||||
discussion_topics.id=#{entry.discussion_topic_id}
|
||||
LIMIT 1
|
||||
SQL
|
||||
discussion_topics.id=#{entry.discussion_topic_id}").first
|
||||
|
||||
# even if there's a group, we're only doing the one student on this pass,
|
||||
# since other group members will have their own row from the main query.
|
||||
# but we still need to know the group
|
||||
group = Group.find_by_sql(<<-SQL).first if assignment.group_category_id
|
||||
SELECT groups.id FROM groups
|
||||
INNER JOIN group_memberships ON
|
||||
group_memberships.group_id=groups.id AND
|
||||
group_memberships.workflow_state!='deleted' AND
|
||||
group_memberships.user_id=#{entry.user_id}
|
||||
WHERE
|
||||
groups.workflow_state!='deleted' AND
|
||||
groups.group_category_id=#{assignment.group_category_id}
|
||||
LIMIT 1
|
||||
SQL
|
||||
group_id = group && group.id
|
||||
if assignment.group_category_id
|
||||
group_id = Group.joins("
|
||||
INNER JOIN #{GroupMembership.quoted_table_name} ON
|
||||
group_memberships.group_id=groups.id AND
|
||||
group_memberships.workflow_state<>'deleted' AND
|
||||
group_memberships.user_id=#{entry.user_id}").
|
||||
where(group_category_id: assignment.group_category_id).
|
||||
where("workflow_state<>'deleted'").
|
||||
limit(1).
|
||||
pluck(:id)
|
||||
end
|
||||
|
||||
homework = Submission.where(assignment_id: assignment.id, user_id: entry.user_id).first_or_initialize
|
||||
homework.grade_matches_current_submission = homework.score ? false : true
|
||||
|
@ -85,7 +78,4 @@ class EnsureSubmissionsForDiscussions < ActiveRecord::Migration
|
|||
Course.where(:id => touched_course_ids.to_a).update_all(:updated_at => Time.now.utc) unless touched_course_ids.empty?
|
||||
User.where(:id => touched_user_ids.to_a).update_all(:updated_at => Time.now.utc) unless touched_user_ids.empty?
|
||||
end
|
||||
|
||||
def self.down
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,9 @@ class SubmissionCommentConversationFix < ActiveRecord::Migration
|
|||
tag :postdeploy
|
||||
|
||||
def self.up
|
||||
Submission.find_by_sql("SELECT * FROM submissions WHERE id IN (SELECT asset_id FROM conversation_messages WHERE asset_id IS NOT NULL AND body = '')").each do |submission|
|
||||
Submission.where(id: ConversationMessage.select(:asset_id).
|
||||
where("asset_id IS NOT NULL").
|
||||
where(body: '')).each do |submission|
|
||||
submission.create_or_update_conversations!(:destroy) if submission.visible_submission_comments.empty?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,9 @@ class FixUserMergeConversations < ActiveRecord::Migration
|
|||
# (which may merge it with another conversation)
|
||||
ConversationParticipant.find_by_sql(<<-SQL).
|
||||
SELECT conversation_participants.*
|
||||
FROM conversation_participants, (
|
||||
FROM #{ConversationParticipant.quoted_table_name}, (
|
||||
SELECT MIN(id) AS id, user_id, conversation_id
|
||||
FROM conversation_participants
|
||||
FROM #{ConversationParticipant.quoted_table_name}
|
||||
GROUP BY user_id, conversation_id
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY conversation_id
|
||||
|
|
|
@ -204,8 +204,8 @@ describe ActiveRecord::Base do
|
|||
it "should have a valid GROUP BY clause when group_by is used correctly" do
|
||||
conn = ActiveRecord::Base.connection
|
||||
expect {
|
||||
User.find_by_sql "SELECT id, name FROM users GROUP BY #{conn.group_by('id', 'name')}"
|
||||
User.find_by_sql "SELECT id, name FROM (SELECT id, name FROM users) u GROUP BY #{conn.group_by('id', 'name')}"
|
||||
User.find_by_sql "SELECT id, name FROM #{User.quoted_table_name} GROUP BY #{conn.group_by('id', 'name')}"
|
||||
User.find_by_sql "SELECT id, name FROM (SELECT id, name FROM #{User.quoted_table_name}) u GROUP BY #{conn.group_by('id', 'name')}"
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue