torque-postgresql 3.1.0 → 3.2.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.
- checksums.yaml +4 -4
 - data/lib/torque/postgresql/adapter/database_statements.rb +13 -15
 - data/lib/torque/postgresql/adapter/schema_creation.rb +3 -9
 - data/lib/torque/postgresql/adapter/schema_statements.rb +5 -0
 - data/lib/torque/postgresql/auxiliary_statement/recursive.rb +149 -0
 - data/lib/torque/postgresql/auxiliary_statement/settings.rb +74 -22
 - data/lib/torque/postgresql/auxiliary_statement.rb +39 -40
 - data/lib/torque/postgresql/base.rb +11 -1
 - data/lib/torque/postgresql/config.rb +5 -1
 - data/lib/torque/postgresql/inheritance.rb +3 -1
 - data/lib/torque/postgresql/railtie.rb +5 -1
 - data/lib/torque/postgresql/relation/auxiliary_statement.rb +28 -15
 - data/lib/torque/postgresql/version.rb +1 -1
 - data/spec/models/category.rb +2 -0
 - data/spec/schema.rb +7 -1
 - data/spec/tests/auxiliary_statement_spec.rb +374 -35
 - data/spec/tests/schema_spec.rb +9 -0
 - metadata +5 -2
 
| 
         @@ -21,7 +21,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       21 
21 
     | 
    
         
             
                  end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       24 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 24 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
         
     | 
| 
       25 
25 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
         
     | 
| 
       26 
26 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       27 
27 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -34,7 +34,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       34 
34 
     | 
    
         
             
                  end
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                  result = 'WITH "comments" AS (SELECT DISTINCT ON ( "comments"."user_id" )'
         
     | 
| 
       37 
     | 
    
         
            -
                  result << ' "comments"." 
     | 
| 
      
 37 
     | 
    
         
            +
                  result << ' "comments"."content" AS last_comment, "comments"."user_id"'
         
     | 
| 
       38 
38 
     | 
    
         
             
                  result << ' FROM "comments" ORDER BY "comments"."user_id" ASC,'
         
     | 
| 
       39 
39 
     | 
    
         
             
                  result << ' "comments"."id" DESC) SELECT "users".*,'
         
     | 
| 
       40 
40 
     | 
    
         
             
                  result << ' "comments"."last_comment" FROM "users" INNER JOIN "comments"'
         
     | 
| 
         @@ -49,7 +49,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       49 
49 
     | 
    
         
             
                  end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
51 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       52 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 52 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."slug" AS comment_slug, "comments"."user_id" FROM "comments")'
         
     | 
| 
       53 
53 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_content", "comments"."comment_slug" FROM "users"'
         
     | 
| 
       54 
54 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       55 
55 
     | 
    
         
             
                  expect(subject.with(:comments, select: {slug: :comment_slug}).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -62,7 +62,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       62 
62 
     | 
    
         
             
                  end
         
     | 
| 
       63 
63 
     | 
    
         | 
| 
       64 
64 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       65 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 65 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id", "comments"."active" FROM "comments")'
         
     | 
| 
       66 
66 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
         
     | 
| 
       67 
67 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id" AND "comments"."active" = "users"."active"'
         
     | 
| 
       68 
68 
     | 
    
         
             
                  expect(subject.with(:comments, join: {active: :active}).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -75,7 +75,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       75 
75 
     | 
    
         
             
                  end
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       78 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 78 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id"'
         
     | 
| 
       79 
79 
     | 
    
         
             
                  result << ' FROM "comments" WHERE "comments"."active" = $1)'
         
     | 
| 
       80 
80 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
         
     | 
| 
       81 
81 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
         @@ -91,7 +91,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       91 
91 
     | 
    
         
             
                  query = subject.where(id: 2).with(:comments)
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       94 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 94 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments"'
         
     | 
| 
       95 
95 
     | 
    
         
             
                  result << ' WHERE "comments"."id" = $1)'
         
     | 
| 
       96 
96 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_content" FROM "users"'
         
     | 
| 
       97 
97 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
         @@ -108,7 +108,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       108 
108 
     | 
    
         
             
                  end
         
     | 
| 
       109 
109 
     | 
    
         | 
| 
       110 
110 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       111 
     | 
    
         
            -
                  result << ' (SELECT  
     | 
| 
      
 111 
     | 
    
         
            +
                  result << ' (SELECT MAX(id) AS comment_id, "comments"."user_id" FROM "comments")'
         
     | 
| 
       112 
112 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
         
     | 
| 
       113 
113 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       114 
114 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -121,7 +121,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       121 
121 
     | 
    
         
             
                  end
         
     | 
| 
       122 
122 
     | 
    
         | 
| 
       123 
123 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       124 
     | 
    
         
            -
                  result << ' (SELECT  
     | 
| 
      
 124 
     | 
    
         
            +
                  result << ' (SELECT ROW_NUMBER() OVER (PARTITION BY ORDER BY "comments"."id") AS comment_id, "comments"."user_id" FROM "comments")'
         
     | 
| 
       125 
125 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
         
     | 
| 
       126 
126 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       127 
127 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -134,7 +134,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       134 
134 
     | 
    
         
             
                  end
         
     | 
| 
       135 
135 
     | 
    
         | 
| 
       136 
136 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       137 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 137 
     | 
    
         
            +
                  result << ' (SELECT MIN("comments"."id") AS comment_id, "comments"."user_id" FROM "comments")'
         
     | 
| 
       138 
138 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."comment_id" FROM "users"'
         
     | 
| 
       139 
139 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       140 
140 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -147,8 +147,8 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       147 
147 
     | 
    
         
             
                    cte.join name: :id, 'a.col' => :col
         
     | 
| 
       148 
148 
     | 
    
         
             
                  end
         
     | 
| 
       149 
149 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
                  result = 'WITH "comments" AS (SELECT "comments"." 
     | 
| 
       151 
     | 
    
         
            -
                  result << ' "comments"." 
     | 
| 
      
 150 
     | 
    
         
            +
                  result = 'WITH "comments" AS (SELECT "comments"."content" AS comment_content,'
         
     | 
| 
      
 151 
     | 
    
         
            +
                  result << ' "comments"."id", "comments"."col" FROM "comments") SELECT "users".*,'
         
     | 
| 
       152 
152 
     | 
    
         
             
                  result << ' "comments"."comment_content" FROM "users" INNER JOIN "comments"'
         
     | 
| 
       153 
153 
     | 
    
         
             
                  result << ' ON "comments"."id" = "users"."name" AND "comments"."col" = "a"."col"'
         
     | 
| 
       154 
154 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -161,8 +161,8 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       161 
161 
     | 
    
         
             
                    cte.join_type :left
         
     | 
| 
       162 
162 
     | 
    
         
             
                  end
         
     | 
| 
       163 
163 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                  result = 'WITH "comments" AS (SELECT "comments"." 
     | 
| 
       165 
     | 
    
         
            -
                  result << ' "comments"." 
     | 
| 
      
 164 
     | 
    
         
            +
                  result = 'WITH "comments" AS (SELECT "comments"."content" AS comment_content,'
         
     | 
| 
      
 165 
     | 
    
         
            +
                  result << ' "comments"."user_id" FROM "comments") SELECT "users".*,'
         
     | 
| 
       166 
166 
     | 
    
         
             
                  result << ' "comments"."comment_content" FROM "users" LEFT OUTER JOIN "comments"'
         
     | 
| 
       167 
167 
     | 
    
         
             
                  result << ' ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       168 
168 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -177,7 +177,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       177 
177 
     | 
    
         
             
                  end
         
     | 
| 
       178 
178 
     | 
    
         | 
| 
       179 
179 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       180 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 180 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS sample_content, "comments"."a_user_id" FROM "comments")'
         
     | 
| 
       181 
181 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments"."sample_content" FROM "users"'
         
     | 
| 
       182 
182 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."a_user_id" = "users"."id"'
         
     | 
| 
       183 
183 
     | 
    
         
             
                  expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -198,8 +198,8 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       198 
198 
     | 
    
         
             
                  query = subject.where(id: 3).with(:comments2)
         
     | 
| 
       199 
199 
     | 
    
         | 
| 
       200 
200 
     | 
    
         
             
                  result = 'WITH '
         
     | 
| 
       201 
     | 
    
         
            -
                  result << '"comments1" AS (SELECT "comments"." 
     | 
| 
       202 
     | 
    
         
            -
                  result << '"comments2" AS (SELECT "comments"." 
     | 
| 
      
 201 
     | 
    
         
            +
                  result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments" WHERE "comments"."id" = $1), '
         
     | 
| 
      
 202 
     | 
    
         
            +
                  result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments" WHERE "comments"."id" = $2)'
         
     | 
| 
       203 
203 
     | 
    
         
             
                  result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
         
     | 
| 
       204 
204 
     | 
    
         
             
                  result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
         
     | 
| 
       205 
205 
     | 
    
         
             
                  result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
         
     | 
| 
         @@ -225,8 +225,8 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       225 
225 
     | 
    
         | 
| 
       226 
226 
     | 
    
         
             
                  it 'can requires another statement as dependency' do
         
     | 
| 
       227 
227 
     | 
    
         
             
                    result = 'WITH '
         
     | 
| 
       228 
     | 
    
         
            -
                    result << '"comments1" AS (SELECT "comments"." 
     | 
| 
       229 
     | 
    
         
            -
                    result << '"comments2" AS (SELECT "comments"." 
     | 
| 
      
 228 
     | 
    
         
            +
                    result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments"), '
         
     | 
| 
      
 229 
     | 
    
         
            +
                    result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments")'
         
     | 
| 
       230 
230 
     | 
    
         
             
                    result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
         
     | 
| 
       231 
231 
     | 
    
         
             
                    result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
         
     | 
| 
       232 
232 
     | 
    
         
             
                    result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
         
     | 
| 
         @@ -235,8 +235,8 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       235 
235 
     | 
    
         | 
| 
       236 
236 
     | 
    
         
             
                  it 'can uses already already set dependent' do
         
     | 
| 
       237 
237 
     | 
    
         
             
                    result = 'WITH '
         
     | 
| 
       238 
     | 
    
         
            -
                    result << '"comments1" AS (SELECT "comments"." 
     | 
| 
       239 
     | 
    
         
            -
                    result << '"comments2" AS (SELECT "comments"." 
     | 
| 
      
 238 
     | 
    
         
            +
                    result << '"comments1" AS (SELECT "comments"."content" AS comment_content1, "comments"."user_id" FROM "comments"), '
         
     | 
| 
      
 239 
     | 
    
         
            +
                    result << '"comments2" AS (SELECT "comments"."content" AS comment_content2, "comments"."user_id" FROM "comments")'
         
     | 
| 
       240 
240 
     | 
    
         
             
                    result << ' SELECT "users".*, "comments1"."comment_content1", "comments2"."comment_content2" FROM "users"'
         
     | 
| 
       241 
241 
     | 
    
         
             
                    result << ' INNER JOIN "comments1" ON "comments1"."user_id" = "users"."id"'
         
     | 
| 
       242 
242 
     | 
    
         
             
                    result << ' INNER JOIN "comments2" ON "comments2"."user_id" = "users"."id"'
         
     | 
| 
         @@ -289,14 +289,14 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       289 
289 
     | 
    
         
             
                    expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /join columns/)
         
     | 
| 
       290 
290 
     | 
    
         
             
                  end
         
     | 
| 
       291 
291 
     | 
    
         | 
| 
       292 
     | 
    
         
            -
                  it 'raises an error when not given the table name as first argument' do
         
     | 
| 
      
 292 
     | 
    
         
            +
                  it 'not raises an error when not given the table name as first argument' do
         
     | 
| 
       293 
293 
     | 
    
         
             
                    klass.send(:auxiliary_statement, :comments) do |cte|
         
     | 
| 
       294 
294 
     | 
    
         
             
                      cte.query 'SELECT * FROM comments'
         
     | 
| 
       295 
295 
     | 
    
         
             
                      cte.attributes content: :comment
         
     | 
| 
       296 
296 
     | 
    
         
             
                      cte.join id: :user_id
         
     | 
| 
       297 
297 
     | 
    
         
             
                    end
         
     | 
| 
       298 
298 
     | 
    
         | 
| 
       299 
     | 
    
         
            -
                    expect{ subject.with(:comments).arel.to_sql }. 
     | 
| 
      
 299 
     | 
    
         
            +
                    expect{ subject.with(:comments).arel.to_sql }.not_to raise_error
         
     | 
| 
       300 
300 
     | 
    
         
             
                  end
         
     | 
| 
       301 
301 
     | 
    
         
             
                end
         
     | 
| 
       302 
302 
     | 
    
         | 
| 
         @@ -309,7 +309,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       309 
309 
     | 
    
         
             
                    end
         
     | 
| 
       310 
310 
     | 
    
         | 
| 
       311 
311 
     | 
    
         
             
                    result = 'WITH "comments" AS'
         
     | 
| 
       312 
     | 
    
         
            -
                    result << ' (SELECT "comments"." 
     | 
| 
      
 312 
     | 
    
         
            +
                    result << ' (SELECT "comments"."content" AS comment, "comments"."user_id" FROM "comments")'
         
     | 
| 
       313 
313 
     | 
    
         
             
                    result << ' SELECT "users".*, "comments"."comment" FROM "users"'
         
     | 
| 
       314 
314 
     | 
    
         
             
                    result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       315 
315 
     | 
    
         
             
                    expect(subject.with(:comments).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -352,7 +352,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       352 
352 
     | 
    
         
             
                    query = subject.with(:comments, args: {id: 1})
         
     | 
| 
       353 
353 
     | 
    
         | 
| 
       354 
354 
     | 
    
         
             
                    result = 'WITH "comments" AS'
         
     | 
| 
       355 
     | 
    
         
            -
                    result << ' (SELECT "comments"." 
     | 
| 
      
 355 
     | 
    
         
            +
                    result << ' (SELECT "comments"."content" AS comment, "comments"."user_id"'
         
     | 
| 
       356 
356 
     | 
    
         
             
                    result << ' FROM "comments" WHERE "comments"."id" = $1)'
         
     | 
| 
       357 
357 
     | 
    
         
             
                    result << ' SELECT "users".*, "comments"."comment" FROM "users"'
         
     | 
| 
       358 
358 
     | 
    
         
             
                    result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
         @@ -370,14 +370,14 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       370 
370 
     | 
    
         
             
                    expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /join columns/)
         
     | 
| 
       371 
371 
     | 
    
         
             
                  end
         
     | 
| 
       372 
372 
     | 
    
         | 
| 
       373 
     | 
    
         
            -
                  it 'raises an error when not given the table name as first argument' do
         
     | 
| 
      
 373 
     | 
    
         
            +
                  it 'not raises an error when not given the table name as first argument' do
         
     | 
| 
       374 
374 
     | 
    
         
             
                    klass.send(:auxiliary_statement, :comments) do |cte|
         
     | 
| 
       375 
375 
     | 
    
         
             
                      cte.query -> { Comment.all }
         
     | 
| 
       376 
376 
     | 
    
         
             
                      cte.attributes content: :comment
         
     | 
| 
       377 
377 
     | 
    
         
             
                      cte.join id: :user_id
         
     | 
| 
       378 
378 
     | 
    
         
             
                    end
         
     | 
| 
       379 
379 
     | 
    
         | 
| 
       380 
     | 
    
         
            -
                    expect{ subject.with(:comments).arel.to_sql }. 
     | 
| 
      
 380 
     | 
    
         
            +
                    expect{ subject.with(:comments).arel.to_sql }.not_to raise_error
         
     | 
| 
       381 
381 
     | 
    
         
             
                  end
         
     | 
| 
       382 
382 
     | 
    
         | 
| 
       383 
383 
     | 
    
         
             
                  it 'raises an error when the result of the proc is an invalid type' do
         
     | 
| 
         @@ -403,7 +403,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       403 
403 
     | 
    
         
             
                    end
         
     | 
| 
       404 
404 
     | 
    
         | 
| 
       405 
405 
     | 
    
         
             
                    result = 'WITH "authors" AS'
         
     | 
| 
       406 
     | 
    
         
            -
                    result << ' (SELECT "authors"." 
     | 
| 
      
 406 
     | 
    
         
            +
                    result << ' (SELECT "authors"."name" AS author_name, "authors"."id" FROM "authors")'
         
     | 
| 
       407 
407 
     | 
    
         
             
                    result << ' SELECT "activity_books".*, "authors"."author_name" FROM "activity_books"'
         
     | 
| 
       408 
408 
     | 
    
         
             
                    result << ' INNER JOIN "authors" ON "authors"."id" = "activity_books"."author_id"'
         
     | 
| 
       409 
409 
     | 
    
         
             
                    expect(subject.with(:authors).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -423,7 +423,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       423 
423 
     | 
    
         
             
                    end
         
     | 
| 
       424 
424 
     | 
    
         | 
| 
       425 
425 
     | 
    
         
             
                    result = 'WITH "authors" AS'
         
     | 
| 
       426 
     | 
    
         
            -
                    result << ' (SELECT "authors"." 
     | 
| 
      
 426 
     | 
    
         
            +
                    result << ' (SELECT "authors"."type" AS author_type, "authors"."id" FROM "authors")'
         
     | 
| 
       427 
427 
     | 
    
         
             
                    result << ' SELECT "activity_books".*, "authors"."author_type" FROM "activity_books"'
         
     | 
| 
       428 
428 
     | 
    
         
             
                    result << ' INNER JOIN "authors" ON "authors"."id" = "activity_books"."author_id"'
         
     | 
| 
       429 
429 
     | 
    
         
             
                    expect(subject.with(:authors).arel.to_sql).to eql(result)
         
     | 
| 
         @@ -434,6 +434,233 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       434 
434 
     | 
    
         
             
                  end
         
     | 
| 
       435 
435 
     | 
    
         
             
                end
         
     | 
| 
       436 
436 
     | 
    
         | 
| 
      
 437 
     | 
    
         
            +
                context 'recursive' do
         
     | 
| 
      
 438 
     | 
    
         
            +
                  let(:klass) { Course }
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
                  it 'correctly build a recursive cte' do
         
     | 
| 
      
 441 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 442 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 443 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 444 
     | 
    
         
            +
                    end
         
     | 
| 
      
 445 
     | 
    
         
            +
             
     | 
| 
      
 446 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 447 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 448 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 449 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 450 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 451 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 452 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 453 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 454 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 455 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 456 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 457 
     | 
    
         
            +
                  end
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                  it 'allows connect to be set to something different using a single value' do
         
     | 
| 
      
 460 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 461 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 462 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 463 
     | 
    
         
            +
                      cte.connect :name
         
     | 
| 
      
 464 
     | 
    
         
            +
                    end
         
     | 
| 
      
 465 
     | 
    
         
            +
             
     | 
| 
      
 466 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 467 
     | 
    
         
            +
                    result << ' SELECT "categories"."name", "categories"."parent_id"'
         
     | 
| 
      
 468 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 469 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_name" IS NULL'
         
     | 
| 
      
 470 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 471 
     | 
    
         
            +
                    result << ' SELECT "categories"."name", "categories"."parent_id"'
         
     | 
| 
      
 472 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 473 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_name" = "all_categories"."name"'
         
     | 
| 
      
 474 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 475 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 476 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 477 
     | 
    
         
            +
                  end
         
     | 
| 
      
 478 
     | 
    
         
            +
             
     | 
| 
      
 479 
     | 
    
         
            +
                  it 'allows a complete different set of connect' do
         
     | 
| 
      
 480 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 481 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 482 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 483 
     | 
    
         
            +
                      cte.connect left: :right
         
     | 
| 
      
 484 
     | 
    
         
            +
                    end
         
     | 
| 
      
 485 
     | 
    
         
            +
             
     | 
| 
      
 486 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 487 
     | 
    
         
            +
                    result << ' SELECT "categories"."left", "categories"."parent_id"'
         
     | 
| 
      
 488 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 489 
     | 
    
         
            +
                    result << ' WHERE "categories"."right" IS NULL'
         
     | 
| 
      
 490 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 491 
     | 
    
         
            +
                    result << ' SELECT "categories"."left", "categories"."parent_id"'
         
     | 
| 
      
 492 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 493 
     | 
    
         
            +
                    result << ' WHERE "categories"."right" = "all_categories"."left"'
         
     | 
| 
      
 494 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 495 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 496 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 497 
     | 
    
         
            +
                  end
         
     | 
| 
      
 498 
     | 
    
         
            +
             
     | 
| 
      
 499 
     | 
    
         
            +
                  it 'allows using an union all' do
         
     | 
| 
      
 500 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 501 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 502 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 503 
     | 
    
         
            +
                      cte.union_all!
         
     | 
| 
      
 504 
     | 
    
         
            +
                    end
         
     | 
| 
      
 505 
     | 
    
         
            +
             
     | 
| 
      
 506 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 507 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 508 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 509 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 510 
     | 
    
         
            +
                    result << ' UNION ALL'
         
     | 
| 
      
 511 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 512 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 513 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 514 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 515 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 516 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 517 
     | 
    
         
            +
                  end
         
     | 
| 
      
 518 
     | 
    
         
            +
             
     | 
| 
      
 519 
     | 
    
         
            +
                  it 'allows having a complete different initiator' do
         
     | 
| 
      
 520 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 521 
     | 
    
         
            +
                      cte.query Category.where(parent_id: 5)
         
     | 
| 
      
 522 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 523 
     | 
    
         
            +
                    end
         
     | 
| 
      
 524 
     | 
    
         
            +
             
     | 
| 
      
 525 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 526 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 527 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 528 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = $1'
         
     | 
| 
      
 529 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 530 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 531 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 532 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 533 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 534 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 535 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 536 
     | 
    
         
            +
                  end
         
     | 
| 
      
 537 
     | 
    
         
            +
             
     | 
| 
      
 538 
     | 
    
         
            +
                  it 'can process the depth of the query' do
         
     | 
| 
      
 539 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 540 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 541 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 542 
     | 
    
         
            +
                      cte.with_depth
         
     | 
| 
      
 543 
     | 
    
         
            +
                    end
         
     | 
| 
      
 544 
     | 
    
         
            +
             
     | 
| 
      
 545 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 546 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", 0 AS depth'
         
     | 
| 
      
 547 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 548 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 549 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 550 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ("all_categories"."depth" + 1) AS depth'
         
     | 
| 
      
 551 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 552 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 553 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 554 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 555 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 556 
     | 
    
         
            +
                  end
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
                  it 'can process and expose the depth of the query' do
         
     | 
| 
      
 559 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 560 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 561 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 562 
     | 
    
         
            +
                      cte.with_depth 'd', start: 10, as: :category_depth
         
     | 
| 
      
 563 
     | 
    
         
            +
                    end
         
     | 
| 
      
 564 
     | 
    
         
            +
             
     | 
| 
      
 565 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 566 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", 10 AS d'
         
     | 
| 
      
 567 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 568 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 569 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 570 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ("all_categories"."d" + 1) AS d'
         
     | 
| 
      
 571 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 572 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 573 
     | 
    
         
            +
                    result << ' ) SELECT "courses".*, "all_categories"."d" AS category_depth FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 574 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 575 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 576 
     | 
    
         
            +
                  end
         
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
                  it 'can process the path of the query' do
         
     | 
| 
      
 579 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 580 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 581 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 582 
     | 
    
         
            +
                      cte.with_path
         
     | 
| 
      
 583 
     | 
    
         
            +
                    end
         
     | 
| 
      
 584 
     | 
    
         
            +
             
     | 
| 
      
 585 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 586 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."id"]::varchar[] AS path'
         
     | 
| 
      
 587 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 588 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 589 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 590 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", array_append("all_categories"."path", "categories"."id"::varchar) AS path'
         
     | 
| 
      
 591 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 592 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 593 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 594 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 595 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 596 
     | 
    
         
            +
                  end
         
     | 
| 
      
 597 
     | 
    
         
            +
             
     | 
| 
      
 598 
     | 
    
         
            +
                  it 'can process and expose the path of the query' do
         
     | 
| 
      
 599 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 600 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 601 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 602 
     | 
    
         
            +
                      cte.with_path 'p', source: :name, as: :category_path
         
     | 
| 
      
 603 
     | 
    
         
            +
                    end
         
     | 
| 
      
 604 
     | 
    
         
            +
             
     | 
| 
      
 605 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 606 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."name"]::varchar[] AS p'
         
     | 
| 
      
 607 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 608 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 609 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 610 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", array_append("all_categories"."p", "categories"."name"::varchar) AS p'
         
     | 
| 
      
 611 
     | 
    
         
            +
                    result << ' FROM "categories", "all_categories"'
         
     | 
| 
      
 612 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "all_categories"."id"'
         
     | 
| 
      
 613 
     | 
    
         
            +
                    result << ' ) SELECT "courses".*, "all_categories"."p" AS category_path FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 614 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 615 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 616 
     | 
    
         
            +
                  end
         
     | 
| 
      
 617 
     | 
    
         
            +
             
     | 
| 
      
 618 
     | 
    
         
            +
                  it 'works with string queries' do
         
     | 
| 
      
 619 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 620 
     | 
    
         
            +
                      cte.query 'SELECT * FROM categories WHERE a IS NULL'
         
     | 
| 
      
 621 
     | 
    
         
            +
                      cte.sub_query 'SELECT * FROM categories, all_categories WHERE all_categories.a = b'
         
     | 
| 
      
 622 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 623 
     | 
    
         
            +
                    end
         
     | 
| 
      
 624 
     | 
    
         
            +
             
     | 
| 
      
 625 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "all_categories" AS ('
         
     | 
| 
      
 626 
     | 
    
         
            +
                    result << 'SELECT * FROM categories WHERE a IS NULL'
         
     | 
| 
      
 627 
     | 
    
         
            +
                    result << ' UNION '
         
     | 
| 
      
 628 
     | 
    
         
            +
                    result << ' SELECT * FROM categories, all_categories WHERE all_categories.a = b'
         
     | 
| 
      
 629 
     | 
    
         
            +
                    result << ') SELECT "courses".* FROM "courses" INNER JOIN "all_categories"'
         
     | 
| 
      
 630 
     | 
    
         
            +
                    result << ' ON "all_categories"."parent_id" = "courses"."id"'
         
     | 
| 
      
 631 
     | 
    
         
            +
                    expect(subject.with(:all_categories).arel.to_sql).to eql(result)
         
     | 
| 
      
 632 
     | 
    
         
            +
                  end
         
     | 
| 
      
 633 
     | 
    
         
            +
             
     | 
| 
      
 634 
     | 
    
         
            +
                  it 'raises an error when query is a string and there is no sub query' do
         
     | 
| 
      
 635 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 636 
     | 
    
         
            +
                      cte.query 'SELECT * FROM categories WHERE a IS NULL'
         
     | 
| 
      
 637 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 638 
     | 
    
         
            +
                    end
         
     | 
| 
      
 639 
     | 
    
         
            +
             
     | 
| 
      
 640 
     | 
    
         
            +
                    expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /generate sub query/)
         
     | 
| 
      
 641 
     | 
    
         
            +
                  end
         
     | 
| 
      
 642 
     | 
    
         
            +
             
     | 
| 
      
 643 
     | 
    
         
            +
                  it 'raises an error when sub query has an invalid type' do
         
     | 
| 
      
 644 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 645 
     | 
    
         
            +
                      cte.query 'SELECT * FROM categories WHERE a IS NULL'
         
     | 
| 
      
 646 
     | 
    
         
            +
                      cte.sub_query -> { 1 }
         
     | 
| 
      
 647 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 648 
     | 
    
         
            +
                    end
         
     | 
| 
      
 649 
     | 
    
         
            +
             
     | 
| 
      
 650 
     | 
    
         
            +
                    expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /query and sub query objects/)
         
     | 
| 
      
 651 
     | 
    
         
            +
                  end
         
     | 
| 
      
 652 
     | 
    
         
            +
             
     | 
| 
      
 653 
     | 
    
         
            +
                  it 'raises an error when connect can be resolved automatically' do
         
     | 
| 
      
 654 
     | 
    
         
            +
                    allow(klass).to receive(:primary_key).and_return(nil)
         
     | 
| 
      
 655 
     | 
    
         
            +
                    klass.send(:recursive_auxiliary_statement, :all_categories) do |cte|
         
     | 
| 
      
 656 
     | 
    
         
            +
                      cte.query Category.all
         
     | 
| 
      
 657 
     | 
    
         
            +
                      cte.join id: :parent_id
         
     | 
| 
      
 658 
     | 
    
         
            +
                    end
         
     | 
| 
      
 659 
     | 
    
         
            +
             
     | 
| 
      
 660 
     | 
    
         
            +
                    expect{ subject.with(:all_categories).arel.to_sql }.to raise_error(ArgumentError, /setting up a proper way to connect/)
         
     | 
| 
      
 661 
     | 
    
         
            +
                  end
         
     | 
| 
      
 662 
     | 
    
         
            +
                end
         
     | 
| 
      
 663 
     | 
    
         
            +
             
     | 
| 
       437 
664 
     | 
    
         
             
                it 'works with count and does not add extra columns' do
         
     | 
| 
       438 
665 
     | 
    
         
             
                  klass.send(:auxiliary_statement, :comments) do |cte|
         
     | 
| 
       439 
666 
     | 
    
         
             
                    cte.query Comment.all
         
     | 
| 
         @@ -441,7 +668,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       441 
668 
     | 
    
         
             
                  end
         
     | 
| 
       442 
669 
     | 
    
         | 
| 
       443 
670 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       444 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 671 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
         
     | 
| 
       445 
672 
     | 
    
         
             
                  result << ' SELECT COUNT(*) FROM "users"'
         
     | 
| 
       446 
673 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       447 
674 
     | 
    
         | 
| 
         @@ -456,7 +683,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       456 
683 
     | 
    
         
             
                  end
         
     | 
| 
       457 
684 
     | 
    
         | 
| 
       458 
685 
     | 
    
         
             
                  result = 'WITH "comments" AS'
         
     | 
| 
       459 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 686 
     | 
    
         
            +
                  result << ' (SELECT "comments"."id" AS value, "comments"."user_id" FROM "comments")'
         
     | 
| 
       460 
687 
     | 
    
         
             
                  result << ' SELECT SUM("comments"."value") FROM "users"'
         
     | 
| 
       461 
688 
     | 
    
         
             
                  result << ' INNER JOIN "comments" ON "comments"."user_id" = "users"."id"'
         
     | 
| 
       462 
689 
     | 
    
         | 
| 
         @@ -472,7 +699,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       472 
699 
     | 
    
         
             
                  expect{ subject.with(:comments).arel.to_sql }.to raise_error(ArgumentError, /object types/)
         
     | 
| 
       473 
700 
     | 
    
         
             
                end
         
     | 
| 
       474 
701 
     | 
    
         | 
| 
       475 
     | 
    
         
            -
                it 'raises an error when  
     | 
| 
      
 702 
     | 
    
         
            +
                it 'raises an error when trying to use a statement that is not defined' do
         
     | 
| 
       476 
703 
     | 
    
         
             
                  expect{ subject.with(:does_not_exist).arel.to_sql }.to raise_error(ArgumentError)
         
     | 
| 
       477 
704 
     | 
    
         
             
                end
         
     | 
| 
       478 
705 
     | 
    
         | 
| 
         @@ -495,7 +722,12 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       495 
722 
     | 
    
         
             
                  expect(subject.protected_methods).to include(:auxiliary_statement)
         
     | 
| 
       496 
723 
     | 
    
         
             
                end
         
     | 
| 
       497 
724 
     | 
    
         | 
| 
       498 
     | 
    
         
            -
                it ' 
     | 
| 
      
 725 
     | 
    
         
            +
                it 'has the recursive configuration' do
         
     | 
| 
      
 726 
     | 
    
         
            +
                  expect(subject.protected_methods).to include(:recursive_cte)
         
     | 
| 
      
 727 
     | 
    
         
            +
                  expect(subject.protected_methods).to include(:recursive_auxiliary_statement)
         
     | 
| 
      
 728 
     | 
    
         
            +
                end
         
     | 
| 
      
 729 
     | 
    
         
            +
             
     | 
| 
      
 730 
     | 
    
         
            +
                it 'allows configure new auxiliary statements' do
         
     | 
| 
       499 
731 
     | 
    
         
             
                  subject.send(:auxiliary_statement, :cte1)
         
     | 
| 
       500 
732 
     | 
    
         
             
                  expect(subject.auxiliary_statements_list).to include(:cte1)
         
     | 
| 
       501 
733 
     | 
    
         
             
                  expect(subject.const_defined?('Cte1_AuxiliaryStatement')).to be_truthy
         
     | 
| 
         @@ -527,7 +759,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       527 
759 
     | 
    
         
             
                  query = subject.with(sample, select: {content: :comment_content}).arel.to_sql
         
     | 
| 
       528 
760 
     | 
    
         | 
| 
       529 
761 
     | 
    
         
             
                  result = 'WITH "comment" AS'
         
     | 
| 
       530 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 762 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
         
     | 
| 
       531 
763 
     | 
    
         
             
                  result << ' SELECT "users".*, "comment"."comment_content" FROM "users"'
         
     | 
| 
       532 
764 
     | 
    
         
             
                  result << ' INNER JOIN "comment" ON "comment"."user_id" = "users"."id"'
         
     | 
| 
       533 
765 
     | 
    
         
             
                  expect(query).to eql(result)
         
     | 
| 
         @@ -538,7 +770,7 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       538 
770 
     | 
    
         
             
                  query = subject.with(sample).arel.to_sql
         
     | 
| 
       539 
771 
     | 
    
         | 
| 
       540 
772 
     | 
    
         
             
                  result = 'WITH "comment" AS'
         
     | 
| 
       541 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 773 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
         
     | 
| 
       542 
774 
     | 
    
         
             
                  result << ' SELECT "users".*, "comment"."comment_content" FROM "users"'
         
     | 
| 
       543 
775 
     | 
    
         
             
                  result << ' INNER JOIN "comment" ON "comment"."user_id" = "users"."id"'
         
     | 
| 
       544 
776 
     | 
    
         
             
                  expect(query).to eql(result)
         
     | 
| 
         @@ -551,13 +783,120 @@ RSpec.describe 'AuxiliaryStatement' do 
     | 
|
| 
       551 
783 
     | 
    
         
             
                  end
         
     | 
| 
       552 
784 
     | 
    
         | 
| 
       553 
785 
     | 
    
         
             
                  result = 'WITH "all_comments" AS'
         
     | 
| 
       554 
     | 
    
         
            -
                  result << ' (SELECT "comments"." 
     | 
| 
      
 786 
     | 
    
         
            +
                  result << ' (SELECT "comments"."content" AS comment_content, "comments"."user_id" FROM "comments")'
         
     | 
| 
       555 
787 
     | 
    
         
             
                  result << ' SELECT "users".*, "all_comments"."comment_content" FROM "users"'
         
     | 
| 
       556 
788 
     | 
    
         
             
                  result << ' INNER JOIN "all_comments" ON "all_comments"."user_id" = "users"."id"'
         
     | 
| 
       557 
789 
     | 
    
         | 
| 
       558 
790 
     | 
    
         
             
                  query = subject.with(sample).arel.to_sql
         
     | 
| 
       559 
791 
     | 
    
         
             
                  expect(query).to eql(result)
         
     | 
| 
       560 
792 
     | 
    
         
             
                end
         
     | 
| 
      
 793 
     | 
    
         
            +
             
     | 
| 
      
 794 
     | 
    
         
            +
                context 'recursive' do
         
     | 
| 
      
 795 
     | 
    
         
            +
                  let(:klass) { Torque::PostgreSQL::AuxiliaryStatement::Recursive }
         
     | 
| 
      
 796 
     | 
    
         
            +
                  subject { Course }
         
     | 
| 
      
 797 
     | 
    
         
            +
             
     | 
| 
      
 798 
     | 
    
         
            +
                  it 'has the external method available' do
         
     | 
| 
      
 799 
     | 
    
         
            +
                    expect(klass).to respond_to(:create)
         
     | 
| 
      
 800 
     | 
    
         
            +
                  end
         
     | 
| 
      
 801 
     | 
    
         
            +
             
     | 
| 
      
 802 
     | 
    
         
            +
                  it 'accepts simple recursive auxiliary statement definition' do
         
     | 
| 
      
 803 
     | 
    
         
            +
                    settings = { join: { id: :parent_id } }
         
     | 
| 
      
 804 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 805 
     | 
    
         
            +
             
     | 
| 
      
 806 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 807 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 808 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 809 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 810 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 811 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 812 
     | 
    
         
            +
                    result << ' FROM "categories", "category"'
         
     | 
| 
      
 813 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "category"."id"'
         
     | 
| 
      
 814 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 815 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 816 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 817 
     | 
    
         
            +
                  end
         
     | 
| 
      
 818 
     | 
    
         
            +
             
     | 
| 
      
 819 
     | 
    
         
            +
                  it 'accepts a connect option' do
         
     | 
| 
      
 820 
     | 
    
         
            +
                    settings = { join: { id: :parent_id }, connect: { a: :b } }
         
     | 
| 
      
 821 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 822 
     | 
    
         
            +
             
     | 
| 
      
 823 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 824 
     | 
    
         
            +
                    result << ' SELECT "categories"."a", "categories"."parent_id"'
         
     | 
| 
      
 825 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 826 
     | 
    
         
            +
                    result << ' WHERE "categories"."b" IS NULL'
         
     | 
| 
      
 827 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 828 
     | 
    
         
            +
                    result << ' SELECT "categories"."a", "categories"."parent_id"'
         
     | 
| 
      
 829 
     | 
    
         
            +
                    result << ' FROM "categories", "category"'
         
     | 
| 
      
 830 
     | 
    
         
            +
                    result << ' WHERE "categories"."b" = "category"."a"'
         
     | 
| 
      
 831 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 832 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 833 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 834 
     | 
    
         
            +
                  end
         
     | 
| 
      
 835 
     | 
    
         
            +
             
     | 
| 
      
 836 
     | 
    
         
            +
                  it 'accepts an union all option' do
         
     | 
| 
      
 837 
     | 
    
         
            +
                    settings = { join: { id: :parent_id }, union_all: true }
         
     | 
| 
      
 838 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 839 
     | 
    
         
            +
             
     | 
| 
      
 840 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 841 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 842 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 843 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 844 
     | 
    
         
            +
                    result << ' UNION ALL'
         
     | 
| 
      
 845 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id"'
         
     | 
| 
      
 846 
     | 
    
         
            +
                    result << ' FROM "categories", "category"'
         
     | 
| 
      
 847 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "category"."id"'
         
     | 
| 
      
 848 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 849 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 850 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 851 
     | 
    
         
            +
                  end
         
     | 
| 
      
 852 
     | 
    
         
            +
             
     | 
| 
      
 853 
     | 
    
         
            +
                  it 'accepts a sub query option' do
         
     | 
| 
      
 854 
     | 
    
         
            +
                    settings = { join: { id: :parent_id }, sub_query: Category.where(active: true) }
         
     | 
| 
      
 855 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 856 
     | 
    
         
            +
             
     | 
| 
      
 857 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 858 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id" FROM "categories"'
         
     | 
| 
      
 859 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 860 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id" FROM "categories", "category" WHERE "categories"."active" = $1'
         
     | 
| 
      
 861 
     | 
    
         
            +
                    result << ' ) SELECT "courses".* FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 862 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 863 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 864 
     | 
    
         
            +
                  end
         
     | 
| 
      
 865 
     | 
    
         
            +
             
     | 
| 
      
 866 
     | 
    
         
            +
                  it 'accepts a depth option' do
         
     | 
| 
      
 867 
     | 
    
         
            +
                    settings = { join: { id: :parent_id }, with_depth: { name: 'a', start: 5, as: 'b' } }
         
     | 
| 
      
 868 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 869 
     | 
    
         
            +
             
     | 
| 
      
 870 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 871 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", 5 AS a'
         
     | 
| 
      
 872 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 873 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 874 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 875 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ("category"."a" + 1) AS a'
         
     | 
| 
      
 876 
     | 
    
         
            +
                    result << ' FROM "categories", "category"'
         
     | 
| 
      
 877 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "category"."id"'
         
     | 
| 
      
 878 
     | 
    
         
            +
                    result << ' ) SELECT "courses".*, "category"."a" AS b FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 879 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 880 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 881 
     | 
    
         
            +
                  end
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
                  it 'accepts a path option' do
         
     | 
| 
      
 884 
     | 
    
         
            +
                    settings = { join: { id: :parent_id }, with_path: { name: 'a', source: 'b', as: 'c' } }
         
     | 
| 
      
 885 
     | 
    
         
            +
                    query = subject.with(klass.create(Category.all), **settings).arel.to_sql
         
     | 
| 
      
 886 
     | 
    
         
            +
             
     | 
| 
      
 887 
     | 
    
         
            +
                    result = 'WITH RECURSIVE "category" AS ('
         
     | 
| 
      
 888 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", ARRAY["categories"."b"]::varchar[] AS a'
         
     | 
| 
      
 889 
     | 
    
         
            +
                    result << ' FROM "categories"'
         
     | 
| 
      
 890 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" IS NULL'
         
     | 
| 
      
 891 
     | 
    
         
            +
                    result << ' UNION'
         
     | 
| 
      
 892 
     | 
    
         
            +
                    result << ' SELECT "categories"."id", "categories"."parent_id", array_append("category"."a", "categories"."b"::varchar) AS a'
         
     | 
| 
      
 893 
     | 
    
         
            +
                    result << ' FROM "categories", "category"'
         
     | 
| 
      
 894 
     | 
    
         
            +
                    result << ' WHERE "categories"."parent_id" = "category"."id"'
         
     | 
| 
      
 895 
     | 
    
         
            +
                    result << ' ) SELECT "courses".*, "category"."a" AS c FROM "courses" INNER JOIN "category"'
         
     | 
| 
      
 896 
     | 
    
         
            +
                    result << ' ON "category"."parent_id" = "courses"."id"'
         
     | 
| 
      
 897 
     | 
    
         
            +
                    expect(query).to eql(result)
         
     | 
| 
      
 898 
     | 
    
         
            +
                  end
         
     | 
| 
      
 899 
     | 
    
         
            +
                end
         
     | 
| 
       561 
900 
     | 
    
         
             
              end
         
     | 
| 
       562 
901 
     | 
    
         | 
| 
       563 
902 
     | 
    
         
             
              context 'on settings' do
         
     |