active_record_extended_telescope 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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