deecay / redmine_pivot_table

This Redmine plugin allows you to generate pivot table for issue analysis.
MIT License
52 stars 38 forks source link

Error when opening after sorting by Tracker #54

Closed kfischer-okarin closed 5 years ago

kfischer-okarin commented 5 years ago

Reproduction Steps

1) Open Issues tab of any project 2) Sort by Tracker column 3) Click on the Pivot Tab

Error log

Query::StatementInvalid (PG::DuplicateAlias: ERROR:  table name "trackers" specified more than once
: SELECT  "issues"."id" AS t0_r0, "issues"."tracker_id" AS t0_r1, "issues"."project_id" AS t0_r2, "issues"."subject" AS t0_r3, "issues"."description" AS t0_r4, "issues"."due_date" AS t0_r5, "issues"."category_id" AS t0_r6, "issues"."status_id" AS t0_r7, "issues"."assigned_to_id" AS t0_r8, "issues"."priority_id" AS t0_r9, "issues"."fixed_version_id" AS t0_r10, "issues"."author_id" AS t0_r11, "issues"."lock_version" AS t0_r12, "issues"."created_on" AS t0_r13, "issues"."updated_on" AS t0_r14, "issues"."start_date" AS t0_r15, "issues"."done_ratio" AS t0_r16, "issues"."estimated_hours" AS t0_r17, "issues"."parent_id" AS t0_r18, "issues"."root_id" AS t0_r19, "issues"."lft" AS t0_r20, "issues"."rgt" AS t0_r21, "issues"."is_private" AS t0_r22, "issues"."closed_on" AS t0_r23, "issues"."actual_start_date" AS t0_r24, "issues"."actual_due_date" AS t0_r25, "issue_statuses"."id" AS t1_r0, "issue_statuses"."name" AS t1_r1, "issue_statuses"."is_closed" AS t1_r2, "issue_statuses"."position" AS t1_r3, "issue_statuses"."default_done_ratio" AS t1_r4, "issue_statuses"."lgc_color" AS t1_r5, "projects"."id" AS t2_r0, "projects"."name" AS t2_r1, "projects"."description" AS t2_r2, "projects"."homepage" AS t2_r3, "projects"."is_public" AS t2_r4, "projects"."parent_id" AS t2_r5, "projects"."created_on" AS t2_r6, "projects"."updated_on" AS t2_r7, "projects"."identifier" AS t2_r8, "projects"."status" AS t2_r9, "projects"."lft" AS t2_r10, "projects"."rgt" AS t2_r11, "projects"."inherit_members" AS t2_r12, "projects"."default_version_id" AS t2_r13, "projects"."default_assigned_to_id" AS t2_r14, "projects"."lgc_options" AS t2_r15, "users"."id" AS t3_r0, "users"."login" AS t3_r1, "users"."hashed_password" AS t3_r2, "users"."firstname" AS t3_r3, "users"."lastname" AS t3_r4, "users"."admin" AS t3_r5, "users"."status" AS t3_r6, "users"."last_login_on" AS t3_r7, "users"."language" AS t3_r8, "users"."auth_source_id" AS t3_r9, "users"."created_on" AS t3_r10, "users"."updated_on" AS t3_r11, "users"."type" AS t3_r12, "users"."identity_url" AS t3_r13, "users"."mail_notification" AS t3_r14, "users"."salt" AS t3_r15, "users"."must_change_passwd" AS t3_r16, "users"."passwd_changed_on" AS t3_r17, "trackers"."id" AS t4_r0, "trackers"."name" AS t4_r1, "trackers"."is_in_chlog" AS t4_r2, "trackers"."position" AS t4_r3, "trackers"."is_in_roadmap" AS t4_r4, "trackers"."fields_bits" AS t4_r5, "trackers"."default_status_id" AS t4_r6, "enumerations"."id" AS t5_r0, "enumerations"."name" AS t5_r1, "enumerations"."position" AS t5_r2, "enumerations"."is_default" AS t5_r3, "enumerations"."type" AS t5_r4, "enumerations"."active" AS t5_r5, "enumerations"."project_id" AS t5_r6, "enumerations"."parent_id" AS t5_r7, "enumerations"."position_name" AS t5_r8, "issue_categories"."id" AS t6_r0, "issue_categories"."project_id" AS t6_r1, "issue_categories"."name" AS t6_r2, "issue_categories"."assigned_to_id" AS t6_r3, "versions"."id" AS t7_r0, "versions"."project_id" AS t7_r1, "versions"."name" AS t7_r2, "versions"."description" AS t7_r3, "versions"."effective_date" AS t7_r4, "versions"."created_on" AS t7_r5, "versions"."updated_on" AS t7_r6, "versions"."wiki_page_title" AS t7_r7, "versions"."status" AS t7_r8, "versions"."sharing" AS t7_r9 FROM "issues" INNER JOIN "projects" ON "projects"."id" = "issues"."project_id" INNER JOIN "issue_statuses" ON "issue_statuses"."id" = "issues"."status_id" LEFT OUTER JOIN "users" ON "users"."id" = "issues"."assigned_to_id" LEFT OUTER JOIN "trackers" ON "trackers"."id" = "issues"."tracker_id" LEFT OUTER JOIN "enumerations" ON "enumerations"."id" = "issues"."priority_id" AND "enumerations"."type" IN ('IssuePriority') LEFT OUTER JOIN "issue_categories" ON "issue_categories"."id" = "issues"."category_id" LEFT OUTER JOIN "versions" ON "versions"."id" = "issues"."fixed_version_id" LEFT OUTER JOIN trackers ON trackers.id = issues.tracker_id WHERE (projects.status <> 9 AND EXISTS (SELECT 1 AS one FROM enabled_modules em WHERE em.project_id = projects.id AND em.name='issue_tracking')) AND ((issues.status_id IN (SELECT id FROM issue_statuses WHERE is_closed='f')) AND projects.lft >= 3 AND projects.rgt <= 182)  ORDER BY trackers.position DESC, issues.id DESC LIMIT 1000 OFFSET 0):
  app/models/issue_query.rb:312:in `rescue in issues'
  app/models/issue_query.rb:274:in `issues'
  plugins/redmine_pivot_table/app/controllers/pivottables_controller.rb:65:in `index'
  lib/redmine/sudo_mode.rb:63:in `sudo_mode'

About the error cause

The line that seems to cause the problem is: https://github.com/deecay/redmine_pivot_table/blob/9c38fa89642dda6b9a826626d6d62242ecdbb7dd/app/controllers/pivottables_controller.rb#L65

Which seems to collide with joins_for_order_statement which already LEFT JOINs the tracker table in case tracker is the sorting column.

https://github.com/redmine/redmine/blob/3.4-stable/app/models/issue_query.rb#L284

def issues(options={})
    order_option = [group_by_sort_order, (options[:order] || sort_clause)].flatten.reject(&:blank?)

    scope = Issue.visible.
      ...
      order(order_option).
      joins(joins_for_order_statement(order_option.join(','))).
      ...