active_record_query_fixer 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecd63505e1bd2832e3c0d25b29695a056ea45753244c9e0df443a921dbca9e95
4
- data.tar.gz: 13393c3e1fffd4edfaedfcf720c2e4200e60761af8e9cd57471bc3d58965cba2
3
+ metadata.gz: e42bc2e925978449204db3564990728f9d82b66da3c977f74cadaf502095e1a8
4
+ data.tar.gz: 749e0f1224b32818616e91487cd93ec9ef0cd47ed3cb716be41f8748ac777289
5
5
  SHA512:
6
- metadata.gz: 8cde6df550b51fba75fd4a65837d7a949727698c76824cefa34a6dd4054c822afe852462ed0e63125734b8230ce979f6b53190b05bd5237c04d4b09d87d40282
7
- data.tar.gz: 51aacd618be7155fa7d8bd94bf78c9cbbc0671822b373baf730e926f74acde591b3b787684c49e9e3a07392799f518b52900147f3795dea9319cf5630ac93728
6
+ metadata.gz: 9bda979fc9bade5a2d07435866be6290eeeb20d876462de6a598e070c9d2ec636251b7bfc190a4491c5fdcd6a994a7e9a8e6362a38ba44458c0a3a7a895edb7f
7
+ data.tar.gz: 542b47e254a9001b151c534ce251df809d0be23867fd42f6146af6d1b1e5ae25db63a045a175a39420abd1bb2f36957d2cc160d1132066f0a4064aca05f436c2
@@ -19,25 +19,25 @@ class ActiveRecordQueryFixer
19
19
  fix_reference_group if fix_reference_group?
20
20
  fix_order_group if fix_order_group?
21
21
  fix_order_select_distinct if fix_order_select_distinct?
22
- fix_select_group if @query.values[:select] && @query.values[:group]
22
+ fix_select_group if query.values[:select] && query.values[:group]
23
23
 
24
24
  self
25
25
  end
26
26
 
27
27
  def fix_select_group
28
28
  select_targets.each do |select_target|
29
- fields = select_target.dig!("ResTarget", "val", "ColumnRef", "fields")
30
- next if fields.length != 2
29
+ fields = select_target.dig!("ResTarget", "val").dig("ColumnRef", "fields")
30
+ next if !fields || fields.length != 2
31
31
 
32
32
  table = fields[0].dig("String", "str")
33
33
  column = fields[1].dig("String", "str")
34
34
 
35
35
  if column
36
36
  # A table and a column has been selected - make sure to group by that
37
- @query = @query.group("#{table}.#{column}")
37
+ @query = query.group("#{table}.#{column}")
38
38
  elsif fields[1].key?("A_Star")
39
39
  # A table and a star has been selected - assume the primary key is called "id" and group by that
40
- @query = @query.group("#{table}.id")
40
+ @query = query.group("#{table}.id")
41
41
  end
42
42
  end
43
43
 
@@ -45,7 +45,7 @@ class ActiveRecordQueryFixer
45
45
  end
46
46
 
47
47
  def fix_order_group
48
- @query = @query.group(@query.model.arel_table[@query.model.primary_key])
48
+ @query = query.group(query.model.arel_table[query.model.primary_key])
49
49
 
50
50
  sort_targets.each do |sort_target|
51
51
  fields = sort_target.dig("SortBy", "node", "ColumnRef", "fields")
@@ -54,15 +54,14 @@ class ActiveRecordQueryFixer
54
54
  table = fields.dig(0, "String", "str")
55
55
  column = fields.dig(1, "String", "str")
56
56
 
57
- @query = @query.group("#{table}.#{column}") if table && column
57
+ @query = query.group("#{table}.#{column}") if table && column
58
58
  end
59
59
 
60
60
  self
61
61
  end
62
62
 
63
63
  def fix_order_select_distinct
64
- changed = false
65
- select_defined = @query.values[:select].present?
64
+ select_appends = []
66
65
 
67
66
  sort_targets.each do |sort_target|
68
67
  fields = sort_target.dig("SortBy", "node", "ColumnRef", "fields")
@@ -73,21 +72,25 @@ class ActiveRecordQueryFixer
73
72
 
74
73
  next if !table || !column
75
74
 
76
- @query = @query.select("#{table}.#{column} AS active_record_query_fixer_#{@count_select}")
77
- changed = true
75
+ select_appends << "#{table}.#{column} AS active_record_query_fixer_#{@count_select}"
78
76
  @count_select += 1
79
77
  end
80
78
 
81
- @query = @query.select("#{@query.table_name}.*") if changed && !select_defined
79
+ # Start by prepending a wild-card select before doing the fix-selects to avoid any issues with `DISTINCT COUNT`
80
+ prepend_table_wildcard if !table_wildcard_prepended? && select_appends.any? && query.values[:select].blank?
81
+
82
+ select_appends.each do |select_append|
83
+ @query = query.select(select_append)
84
+ end
82
85
 
83
86
  self
84
87
  end
85
88
 
86
89
  def fix_reference_group
87
- @query = @query.group(@query.model.arel_table[@query.model.primary_key])
90
+ @query = query.group(query.model.arel_table[query.model.primary_key])
88
91
 
89
- @query.values[:references].each do |reference|
90
- @query = @query.group("#{reference}.id")
92
+ query.values[:references].each do |reference|
93
+ @query = query.group("#{reference}.id")
91
94
  end
92
95
 
93
96
  self
@@ -96,20 +99,40 @@ class ActiveRecordQueryFixer
96
99
  private
97
100
 
98
101
  def fix_order_group?
99
- @query.values[:joins].blank? && @query.values[:distinct].present? && @query.values[:order].present? ||
100
- @query.values[:group].present? && @query.values[:order].present?
102
+ query.values[:joins].blank? && query.values[:distinct].present? && query.values[:order].present? ||
103
+ query.values[:group].present? && query.values[:order].present?
101
104
  end
102
105
 
103
106
  def fix_order_select_distinct?
104
- @query.values[:distinct].present? && @query.values[:order].present?
107
+ query.values[:distinct].present? && query.values[:order].present?
105
108
  end
106
109
 
107
110
  def fix_reference_group?
108
- @query.values[:references].present? && @query.values[:group].present?
111
+ query.values[:references].present? && query.values[:group].present?
109
112
  end
110
113
 
111
114
  def parsed_query
112
- @parsed_query ||= PgQuery.parse(@query.to_sql)
115
+ @parsed_query ||= PgQuery.parse(query.to_sql)
116
+ end
117
+
118
+ # Prepends 'table_name.*' to the query. It needs to be pre-pended in case a `COUNT` or another aggregate function has been added to work with `DISTINCT`.
119
+ def prepend_table_wildcard
120
+ old_select = query.values[:select]&.clone || []
121
+ old_select = old_select.keep_if { |select_statement| select_statement != select_table_wildcard_sql }
122
+
123
+ @query = query.except(:select).select(select_table_wildcard_sql)
124
+
125
+ old_select.each do |select_statement|
126
+ @query = query.select(select_statement)
127
+ end
128
+ end
129
+
130
+ def select_table_wildcard_sql
131
+ @select_table_wildcard_sql ||= "#{query.table_name}.*"
132
+ end
133
+
134
+ def table_wildcard_prepended?
135
+ query.values[:select]&.first == select_table_wildcard_sql
113
136
  end
114
137
 
115
138
  def select_statement
@@ -1,3 +1,3 @@
1
1
  class ActiveRecordQueryFixer
2
- VERSION = "0.0.11".freeze
2
+ VERSION = "0.0.12".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_query_fixer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-19 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dig_bang