active_record_extended_telescope 2.0.1

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +870 -0
  3. data/lib/active_record_extended.rb +10 -0
  4. data/lib/active_record_extended/active_record.rb +25 -0
  5. data/lib/active_record_extended/active_record/relation_patch.rb +50 -0
  6. data/lib/active_record_extended/arel.rb +7 -0
  7. data/lib/active_record_extended/arel/aggregate_function_name.rb +40 -0
  8. data/lib/active_record_extended/arel/nodes.rb +49 -0
  9. data/lib/active_record_extended/arel/predications.rb +50 -0
  10. data/lib/active_record_extended/arel/sql_literal.rb +16 -0
  11. data/lib/active_record_extended/arel/visitors/postgresql_decorator.rb +122 -0
  12. data/lib/active_record_extended/patch/5_1/where_clause.rb +11 -0
  13. data/lib/active_record_extended/patch/5_2/where_clause.rb +11 -0
  14. data/lib/active_record_extended/predicate_builder/array_handler_decorator.rb +20 -0
  15. data/lib/active_record_extended/query_methods/any_of.rb +93 -0
  16. data/lib/active_record_extended/query_methods/either.rb +62 -0
  17. data/lib/active_record_extended/query_methods/inet.rb +88 -0
  18. data/lib/active_record_extended/query_methods/json.rb +329 -0
  19. data/lib/active_record_extended/query_methods/select.rb +118 -0
  20. data/lib/active_record_extended/query_methods/unionize.rb +249 -0
  21. data/lib/active_record_extended/query_methods/where_chain.rb +132 -0
  22. data/lib/active_record_extended/query_methods/window.rb +93 -0
  23. data/lib/active_record_extended/query_methods/with_cte.rb +150 -0
  24. data/lib/active_record_extended/utilities/order_by.rb +77 -0
  25. data/lib/active_record_extended/utilities/support.rb +178 -0
  26. data/lib/active_record_extended/version.rb +5 -0
  27. data/lib/active_record_extended_telescope.rb +4 -0
  28. data/spec/active_record_extended_spec.rb +7 -0
  29. data/spec/query_methods/any_of_spec.rb +131 -0
  30. data/spec/query_methods/array_query_spec.rb +64 -0
  31. data/spec/query_methods/either_spec.rb +59 -0
  32. data/spec/query_methods/hash_query_spec.rb +45 -0
  33. data/spec/query_methods/inet_query_spec.rb +112 -0
  34. data/spec/query_methods/json_spec.rb +157 -0
  35. data/spec/query_methods/select_spec.rb +115 -0
  36. data/spec/query_methods/unionize_spec.rb +165 -0
  37. data/spec/query_methods/window_spec.rb +51 -0
  38. data/spec/query_methods/with_cte_spec.rb +50 -0
  39. data/spec/spec_helper.rb +28 -0
  40. data/spec/sql_inspections/any_of_sql_spec.rb +41 -0
  41. data/spec/sql_inspections/arel/aggregate_function_name_spec.rb +41 -0
  42. data/spec/sql_inspections/arel/array_spec.rb +63 -0
  43. data/spec/sql_inspections/arel/inet_spec.rb +66 -0
  44. data/spec/sql_inspections/contains_sql_queries_spec.rb +47 -0
  45. data/spec/sql_inspections/either_sql_spec.rb +55 -0
  46. data/spec/sql_inspections/json_sql_spec.rb +82 -0
  47. data/spec/sql_inspections/unionize_sql_spec.rb +124 -0
  48. data/spec/sql_inspections/window_sql_spec.rb +98 -0
  49. data/spec/sql_inspections/with_cte_sql_spec.rb +95 -0
  50. data/spec/support/database_cleaner.rb +15 -0
  51. data/spec/support/models.rb +68 -0
  52. metadata +245 -0
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Active Record WINDOW Query inspection" do
6
+ describe "#define_window" do
7
+ context "when there is a single defined window" do
8
+ it "should only contain a single defined window statement at the bottom" do
9
+ query = Tag.define_window(:w_test).partition_by(:user_id).to_sql
10
+ expect(query).to eq('SELECT "tags".* FROM "tags" WINDOW w_test AS (PARTITION BY user_id)')
11
+ end
12
+
13
+ it "should return a single defined window with a defined ORDER BY" do
14
+ query = Tag.define_window(:w_test).partition_by(:user_id, order_by: { tags: { user_id: :desc } }).to_sql
15
+ expect(query).to end_with("WINDOW w_test AS (PARTITION BY user_id ORDER BY tags.user_id DESC)")
16
+ end
17
+
18
+ it "should place the window function below the WHERE and GROUP BY statements" do
19
+ query = Tag.define_window(:w_test).partition_by(:user_id).where(id: 1).group(:user_id).to_sql
20
+ expect(query).to eq('SELECT "tags".* FROM "tags" WHERE "tags"."id" = 1 GROUP BY "tags"."user_id" WINDOW w_test AS (PARTITION BY user_id)')
21
+ end
22
+ end
23
+
24
+ context "when there are multiple defined windows" do
25
+ it "should only contain a single defined window statement at the bottom" do
26
+ query =
27
+ Tag
28
+ .define_window(:test).partition_by(:user_id)
29
+ .define_window(:other_window).partition_by(:id)
30
+ .to_sql
31
+
32
+ expect(query).to end_with("WINDOW test AS (PARTITION BY user_id), other_window AS (PARTITION BY id)")
33
+ end
34
+
35
+ it "should contain each windows order by statements" do
36
+ query =
37
+ Tag
38
+ .define_window(:test).partition_by(:user_id, order_by: :id)
39
+ .define_window(:other_window).partition_by(:id, order_by: { tags: :user_id })
40
+ .to_sql
41
+
42
+ expect(query).to end_with("WINDOW test AS (PARTITION BY user_id ORDER BY id), other_window AS (PARTITION BY id ORDER BY tags.user_id ASC)")
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#window_select" do
48
+ let(:query_base) { Tag.define_window(:w).partition_by(:user_id, order_by: :id) }
49
+ let(:expected_end) { "WINDOW w AS (PARTITION BY user_id ORDER BY id)" }
50
+
51
+ context "when using no argument window methods" do
52
+ [:row_to_number, :rank, :dense_rank, :percent_rank, :cume_dist].each do |window_function|
53
+ context "#{window_function.to_s.upcase}()" do
54
+ let(:expected_function) { "#{window_function.to_s.upcase}()" }
55
+ let(:query) do
56
+ query_base.select_window(window_function, over: :w, as: :window_response).to_sql
57
+ end
58
+
59
+ it "appends the function to the select query" do
60
+ expected_start = "SELECT (#{expected_function} OVER w) AS \"window_response\""
61
+ expect(query).to start_with(expected_start).and(end_with(expected_end))
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ context "when using an argument based window method" do
68
+ let(:argument_list) { ["a", 1, :sauce] }
69
+
70
+ { ntile: 1, lag: 2, lead: 3, first_value: 1, last_value: 1, nth_value: 2 }.each_pair do |window_function, arg_count|
71
+ context "#{window_function.to_s.upcase}/#{arg_count}" do
72
+ let(:arguments) { argument_list.first(arg_count) }
73
+ let(:expected_function) { "#{window_function.to_s.upcase}(#{arguments.join(', ')})" }
74
+ let(:query) do
75
+ query_base.select_window(window_function, *arguments, over: :w, as: :window_response).to_sql
76
+ end
77
+
78
+ it "appends the function to the select query" do
79
+ expected_start = "SELECT (#{expected_function} OVER w) AS \"window_response\""
80
+ expect(query).to start_with(expected_start).and(end_with(expected_end))
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ context "when not providing a partition by value" do
87
+ it "should construct a window function" do
88
+ query =
89
+ Tag
90
+ .define_window(:no_args).partition_by(order_by: { tag_number: :desc })
91
+ .select_window(:row_number, over: :no_args, as: :my_row)
92
+ .to_sql
93
+
94
+ expect(query).to eq("SELECT (ROW_NUMBER() OVER no_args) AS \"my_row\" FROM \"tags\" WINDOW no_args AS (ORDER BY tag_number DESC)")
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Active Record WITH CTE tables" do
6
+ let(:with_personal_query) { /WITH.+personal_id_one.+AS \(SELECT.+users.+FROM.+WHERE.+users.+personal_id.+ = 1\)/ }
7
+
8
+ it "should contain WITH statement that creates the CTE table" do
9
+ query = User.with(personal_id_one: User.where(personal_id: 1))
10
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
11
+ .to_sql
12
+ expect(query).to match_regex(with_personal_query)
13
+ end
14
+
15
+ it "will maintain the CTE table when merging" do
16
+ query = User.all
17
+ .merge(User.with(personal_id_one: User.where(personal_id: 1)))
18
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
19
+ .to_sql
20
+
21
+ expect(query).to match_regex(with_personal_query)
22
+ end
23
+
24
+ it "will pipe Children CTE's into the Parent relation" do
25
+ personal_id_one_query = User.where(personal_id: 1)
26
+ personal_id_two_query = User.where(personal_id: 2)
27
+
28
+ sub_query = personal_id_two_query.with(personal_id_one: personal_id_one_query)
29
+ query = User.all.with(personal_id_two: sub_query)
30
+ expected_order = User.with(
31
+ personal_id_one: personal_id_one_query,
32
+ personal_id_two: personal_id_two_query
33
+ )
34
+
35
+ expect(query.to_sql).to eq(expected_order.to_sql)
36
+ end
37
+
38
+ context "when multiple CTE's" do
39
+ let(:chained_with) do
40
+ User.with(personal_id_one: User.where(personal_id: 1))
41
+ .with(personal_id_two: User.where(personal_id: 2))
42
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
43
+ .joins("JOIN personal_id_two ON personal_id_two.id = users.id")
44
+ .to_sql
45
+ end
46
+
47
+ let(:with_arguments) do
48
+ User.with(personal_id_one: User.where(personal_id: 1), personal_id_two: User.where(personal_id: 2))
49
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
50
+ .joins("JOIN personal_id_two ON personal_id_two.id = users.id")
51
+ .to_sql
52
+ end
53
+
54
+ it "Should only contain a single WITH statement" do
55
+ expect(with_arguments.scan(/WITH/).count).to eq(1)
56
+ expect(with_arguments.scan(/AS/).count).to eq(2)
57
+ end
58
+
59
+ it "Should only contain a single WITH statement when chaining" do
60
+ expect(chained_with.scan(/WITH/).count).to eq(1)
61
+ expect(chained_with.scan(/AS/).count).to eq(2)
62
+ end
63
+ end
64
+
65
+ context "when chaining the recursive method" do
66
+ let(:with_recursive_personal_query) do
67
+ /WITH.+RECURSIVE.+personal_id_one.+AS \(SELECT.+users.+FROM.+WHERE.+users.+personal_id.+ = 1\)/
68
+ end
69
+
70
+ let(:with_recursive) do
71
+ User.with
72
+ .recursive(personal_id_one: User.where(personal_id: 1))
73
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
74
+ .to_sql
75
+ end
76
+
77
+ it "generates an expression with recursive" do
78
+ query = User.with
79
+ .recursive(personal_id_one: User.where(personal_id: 1))
80
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
81
+ .to_sql
82
+
83
+ expect(query).to match_regex(with_recursive_personal_query)
84
+ end
85
+
86
+ it "will maintain the CTE table when merging" do
87
+ sub_query = User.with.recursive(personal_id_one: User.where(personal_id: 1))
88
+ query = User.merge(sub_query)
89
+ .joins("JOIN personal_id_one ON personal_id_one.id = users.id")
90
+ .to_sql
91
+
92
+ expect(query).to match_regex(with_recursive_personal_query)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "database_cleaner"
4
+
5
+ DatabaseCleaner.strategy = :truncation
6
+
7
+ RSpec.configure do |config|
8
+ config.before do
9
+ DatabaseCleaner.start
10
+ end
11
+
12
+ config.after do
13
+ DatabaseCleaner.clean
14
+ end
15
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
6
+
7
+ class User < ApplicationRecord
8
+ has_many :hm_tags, class_name: "Tag"
9
+ has_one :profile_l, class_name: "ProfileL"
10
+ has_one :profile_r, class_name: "ProfileR"
11
+ # attributes
12
+ # t.string "tags", array: true
13
+ # t.integer "number", default: 0
14
+ # t.string "name"
15
+ # t.integer "personal_id"
16
+ # t.hstore "data"
17
+ # t.jsonb "jsonb_data"
18
+ # t.inet "ip"
19
+ # t.cidr "subnet"
20
+ #
21
+ end
22
+
23
+ class StiRecord < ApplicationRecord
24
+ # t.string "type"
25
+ end
26
+
27
+ class AdminSti < StiRecord; end
28
+
29
+ module Namespaced
30
+ def self.table_name_prefix
31
+ "namespaced_"
32
+ end
33
+
34
+ class Record < ApplicationRecord
35
+ # attributes
36
+ # t.inet :ip
37
+ # t.cidr :subnet
38
+ #
39
+ end
40
+ end
41
+
42
+ class Tag < ApplicationRecord
43
+ belongs_to :user
44
+ # attributes: tag_number
45
+ end
46
+
47
+ class ProfileL < ApplicationRecord
48
+ belongs_to :user
49
+ has_one :version, as: :versionable, class_name: "VersionControl"
50
+ # attributes
51
+ # t.integer :likes
52
+ #
53
+ end
54
+
55
+ class ProfileR < ApplicationRecord
56
+ belongs_to :user
57
+ has_one :version, as: :versionable, class_name: "VersionControl"
58
+ # attributes
59
+ # t.integer :dislikes
60
+ #
61
+ end
62
+
63
+ class VersionControl < ApplicationRecord
64
+ belongs_to :versionable, polymorphic: true, optional: false
65
+ # attributes
66
+ # t.jsonb :source, default: {}, null: false
67
+ #
68
+ end
metadata ADDED
@@ -0,0 +1,245 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_extended_telescope
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.1
5
+ platform: ruby
6
+ authors:
7
+ - George Protacio-Karaszi
8
+ - Dan McClain
9
+ - Olivier El Mekki
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2021-02-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '5.1'
22
+ - - "<"
23
+ - !ruby/object:Gem::Version
24
+ version: '6.2'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: '5.1'
32
+ - - "<"
33
+ - !ruby/object:Gem::Version
34
+ version: '6.2'
35
+ - !ruby/object:Gem::Dependency
36
+ name: ar_outer_joins
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.2'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.2'
49
+ - !ruby/object:Gem::Dependency
50
+ name: pg
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "<"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '1.16'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.0'
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '1.16'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: database_cleaner
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.16'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.16'
139
+ description: Adds extended functionality to Activerecord Postgres implementation
140
+ email:
141
+ - georgekaraszi@gmail.com
142
+ - git@danmcclain.net
143
+ - olivier@el-mekki.com
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - README.md
149
+ - lib/active_record_extended.rb
150
+ - lib/active_record_extended/active_record.rb
151
+ - lib/active_record_extended/active_record/relation_patch.rb
152
+ - lib/active_record_extended/arel.rb
153
+ - lib/active_record_extended/arel/aggregate_function_name.rb
154
+ - lib/active_record_extended/arel/nodes.rb
155
+ - lib/active_record_extended/arel/predications.rb
156
+ - lib/active_record_extended/arel/sql_literal.rb
157
+ - lib/active_record_extended/arel/visitors/postgresql_decorator.rb
158
+ - lib/active_record_extended/patch/5_1/where_clause.rb
159
+ - lib/active_record_extended/patch/5_2/where_clause.rb
160
+ - lib/active_record_extended/predicate_builder/array_handler_decorator.rb
161
+ - lib/active_record_extended/query_methods/any_of.rb
162
+ - lib/active_record_extended/query_methods/either.rb
163
+ - lib/active_record_extended/query_methods/inet.rb
164
+ - lib/active_record_extended/query_methods/json.rb
165
+ - lib/active_record_extended/query_methods/select.rb
166
+ - lib/active_record_extended/query_methods/unionize.rb
167
+ - lib/active_record_extended/query_methods/where_chain.rb
168
+ - lib/active_record_extended/query_methods/window.rb
169
+ - lib/active_record_extended/query_methods/with_cte.rb
170
+ - lib/active_record_extended/utilities/order_by.rb
171
+ - lib/active_record_extended/utilities/support.rb
172
+ - lib/active_record_extended/version.rb
173
+ - lib/active_record_extended_telescope.rb
174
+ - spec/active_record_extended_spec.rb
175
+ - spec/query_methods/any_of_spec.rb
176
+ - spec/query_methods/array_query_spec.rb
177
+ - spec/query_methods/either_spec.rb
178
+ - spec/query_methods/hash_query_spec.rb
179
+ - spec/query_methods/inet_query_spec.rb
180
+ - spec/query_methods/json_spec.rb
181
+ - spec/query_methods/select_spec.rb
182
+ - spec/query_methods/unionize_spec.rb
183
+ - spec/query_methods/window_spec.rb
184
+ - spec/query_methods/with_cte_spec.rb
185
+ - spec/spec_helper.rb
186
+ - spec/sql_inspections/any_of_sql_spec.rb
187
+ - spec/sql_inspections/arel/aggregate_function_name_spec.rb
188
+ - spec/sql_inspections/arel/array_spec.rb
189
+ - spec/sql_inspections/arel/inet_spec.rb
190
+ - spec/sql_inspections/contains_sql_queries_spec.rb
191
+ - spec/sql_inspections/either_sql_spec.rb
192
+ - spec/sql_inspections/json_sql_spec.rb
193
+ - spec/sql_inspections/unionize_sql_spec.rb
194
+ - spec/sql_inspections/window_sql_spec.rb
195
+ - spec/sql_inspections/with_cte_sql_spec.rb
196
+ - spec/support/database_cleaner.rb
197
+ - spec/support/models.rb
198
+ homepage: https://github.com/georgekaraszi/ActiveRecordExtended
199
+ licenses:
200
+ - MIT
201
+ metadata: {}
202
+ post_install_message:
203
+ rdoc_options: []
204
+ require_paths:
205
+ - lib
206
+ required_ruby_version: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ version: '2.4'
211
+ required_rubygems_version: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ requirements: []
217
+ rubygems_version: 3.1.4
218
+ signing_key:
219
+ specification_version: 4
220
+ summary: Adds extended functionality to Activerecord Postgres implementation
221
+ test_files:
222
+ - spec/active_record_extended_spec.rb
223
+ - spec/query_methods/any_of_spec.rb
224
+ - spec/query_methods/array_query_spec.rb
225
+ - spec/query_methods/either_spec.rb
226
+ - spec/query_methods/hash_query_spec.rb
227
+ - spec/query_methods/inet_query_spec.rb
228
+ - spec/query_methods/json_spec.rb
229
+ - spec/query_methods/select_spec.rb
230
+ - spec/query_methods/unionize_spec.rb
231
+ - spec/query_methods/window_spec.rb
232
+ - spec/query_methods/with_cte_spec.rb
233
+ - spec/spec_helper.rb
234
+ - spec/sql_inspections/any_of_sql_spec.rb
235
+ - spec/sql_inspections/arel/aggregate_function_name_spec.rb
236
+ - spec/sql_inspections/arel/array_spec.rb
237
+ - spec/sql_inspections/arel/inet_spec.rb
238
+ - spec/sql_inspections/contains_sql_queries_spec.rb
239
+ - spec/sql_inspections/either_sql_spec.rb
240
+ - spec/sql_inspections/json_sql_spec.rb
241
+ - spec/sql_inspections/unionize_sql_spec.rb
242
+ - spec/sql_inspections/window_sql_spec.rb
243
+ - spec/sql_inspections/with_cte_sql_spec.rb
244
+ - spec/support/database_cleaner.rb
245
+ - spec/support/models.rb