postgres_ext 2.1.3 → 2.2.0
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/.gitignore +1 -0
- data/.travis.yml +13 -22
- data/CHANGELOG.md +45 -0
- data/README.md +13 -0
- data/Rakefile +83 -7
- data/docs/querying.md +76 -6
- data/lib/postgres_ext/active_record/relation/predicate_builder.rb +2 -2
- data/lib/postgres_ext/active_record/relation/query_methods.rb +44 -11
- data/lib/postgres_ext/arel/predications.rb +10 -0
- data/lib/postgres_ext/arel/visitors/to_sql.rb +1 -1
- data/lib/postgres_ext/version.rb +1 -1
- data/postgres_ext.gemspec +4 -2
- data/test/arel/array_test.rb +92 -0
- data/{spec/arel/inet_spec.rb → test/arel/inet_test.rb} +6 -6
- data/{spec/queries/array_queries_spec.rb → test/queries/array_queries_test.rb} +22 -14
- data/test/queries/common_table_expression_test.rb +49 -0
- data/{spec/queries/contains_querie_spec.rb → test/queries/contains_test.rb} +5 -5
- data/test/queries/sanity_test.rb +32 -0
- data/test/queries/window_functions_test.rb +64 -0
- data/test/test_helper.rb +38 -0
- metadata +74 -150
- data/spec/arel/array_spec.rb +0 -77
- data/spec/arel/rank_spec.rb +0 -0
- data/spec/dummy/.gitignore +0 -15
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +0 -15
- data/spec/dummy/app/assets/stylesheets/application.css +0 -13
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/person.rb +0 -2
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -56
- data/spec/dummy/config/boot.rb +0 -6
- data/spec/dummy/config/database.yml.example +0 -14
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -33
- data/spec/dummy/config/environments/production.rb +0 -68
- data/spec/dummy/config/environments/test.rb +0 -33
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/inflections.rb +0 -15
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -58
- data/spec/dummy/db/migrate/20120501163758_create_people.rb +0 -15
- data/spec/dummy/db/schema.rb +0 -31
- data/spec/dummy/db/seeds.rb +0 -7
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/lib/tasks/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -25
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/index.html +0 -241
- data/spec/dummy/public/robots.txt +0 -5
- data/spec/dummy/script/rails +0 -6
- data/spec/dummy/spec/factories/people.rb +0 -7
- data/spec/dummy/test/fixtures/.gitkeep +0 -0
- data/spec/dummy/test/functional/.gitkeep +0 -0
- data/spec/dummy/test/integration/.gitkeep +0 -0
- data/spec/dummy/test/performance/browsing_test.rb +0 -12
- data/spec/dummy/test/test_helper.rb +0 -13
- data/spec/dummy/test/unit/.gitkeep +0 -0
- data/spec/dummy/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/dummy/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/dummy/vendor/plugins/.gitkeep +0 -0
- data/spec/queries/common_table_expression_spec.rb +0 -36
- data/spec/queries/sanity_spec.rb +0 -17
- data/spec/queries/window_functions_spec.rb +0 -54
- data/spec/spec_helper.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9078ca33d9a9b96fa41f3082157f2bceb46319b9
|
4
|
+
data.tar.gz: 8797b9642f4c3757d3b450bbdef4ffbcc00dce72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96d7943795f68ab0e4ca85e12ca0d508844d29f78ff7baec44e952bb23c012290ffadceef317d5496a395cb896d1110289a2cf395998a107574a556dabb2e97c
|
7
|
+
data.tar.gz: 75c699237d3dfa87a62099d52dd84a1c77936d0ae730207bf3801bc1acc4112acfd0cf64521c2407cf79199033b025c3eeab91c747ef6b1c2ff3ae9d21c36ed0
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,28 +1,19 @@
|
|
1
1
|
rvm:
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
- 1.9.3
|
3
|
+
- 2.0.0
|
4
|
+
- jruby-19mode
|
5
|
+
|
6
|
+
env: DATABASE_URL=postgres://postgres@localhost/postgres_ext_test
|
5
7
|
|
6
8
|
before_script:
|
7
|
-
|
8
|
-
|
9
|
-
- sudo apt-get remove postgresql postgresql-9.1 -qq --purge
|
10
|
-
- source /etc/lsb-release
|
11
|
-
- echo "deb http://apt.postgresql.org/pub/repos/apt/ $DISTRIB_CODENAME-pgdg main" > pgdg.list
|
12
|
-
- sudo mv pgdg.list /etc/apt/sources.list.d/
|
13
|
-
- wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
|
14
|
-
- sudo apt-get update -qq
|
15
|
-
- sudo apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" install postgresql-9.2 postgresql-contrib-9.2 -qq
|
16
|
-
- sudo /etc/init.d/postgresql stop
|
17
|
-
- sudo cp ./pg_hba.conf /etc/postgresql/9.2/main
|
18
|
-
- sudo /etc/init.d/postgresql start
|
19
|
-
- psql -c 'create database postgres_ext_test;' -U postgres -h localhost
|
20
|
-
- cp spec/dummy/config/database.yml.example spec/dummy/config/database.yml
|
21
|
-
- RAILS_ENV=test rake db:migrate
|
9
|
+
- psql -c 'create database postgres_ext_test;' -U postgres -h localhost
|
10
|
+
- rake db:migrate
|
22
11
|
|
23
12
|
notifications:
|
24
|
-
email:
|
25
|
-
|
26
|
-
|
13
|
+
email:
|
14
|
+
- git@danmcclain.net
|
15
|
+
hipchat:
|
27
16
|
rooms:
|
28
|
-
|
17
|
+
secure: gebjx8Q/jmnNmf6l+SyQHHJjGn9RfA6s4e8sIoRBVt9pomkOCBvHq7++AjpVlqkXcvV6rK2L90rAEPKMP0QUS04vRtRY6LvwmjiQHFo99/gktG6LO+5/QGvy9zbK4PxWe35Yr1F98Gs0mQ+y/ZbU6u8rJsI7DM1iPq2ULzo/QUw=
|
18
|
+
addons:
|
19
|
+
postgresql: '9.3'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,48 @@
|
|
1
|
+
## 2.2.0
|
2
|
+
|
3
|
+
* Adds Arel predications for `ANY` and `ALL` - Dan McClain
|
4
|
+
* Fixes errors with has\_and\_belongs\_to\_many associations - Jacob Swanner
|
5
|
+
* Adds with.recursive for recursive CTEs - Cody Cutrer
|
6
|
+
* Relation.with now accepts Arel::SelectMangers - Dan McClain
|
7
|
+
|
8
|
+
## 2.1.3
|
9
|
+
|
10
|
+
* Fixes Arel 4.0.1 issues - Dan McClain
|
11
|
+
* Prevents coversion of string to order statement - Dan McClain
|
12
|
+
|
13
|
+
## 2.1.2
|
14
|
+
|
15
|
+
* Fixes calls to count when ranking a relation - Dan McClain
|
16
|
+
|
17
|
+
## 2.1.1
|
18
|
+
|
19
|
+
* Fixes cte proxy so that it can create records - Dan McClain
|
20
|
+
|
21
|
+
## 2.1.0
|
22
|
+
|
23
|
+
* Support added for common table expressions - Dan McClain
|
24
|
+
* Support added for rank windowing function - Dan McClain
|
25
|
+
* Insert Code Climate badge into README - Doug Yun
|
26
|
+
|
27
|
+
# 2.0.0
|
28
|
+
|
29
|
+
* JRuby fixes - Dan McClain
|
30
|
+
* Updates docs and description - Dan McClain
|
31
|
+
* Rails 4 support - Dan McClain
|
32
|
+
|
33
|
+
# 1.0.0
|
34
|
+
|
35
|
+
1.0.0 is the last major and minor release for Rails 3.2.x. Postgres\_ext
|
36
|
+
will only receive bug fixes in the future. Also, bug fixes for 1.0.x
|
37
|
+
will come from PRs only, future development efforts are concentrated on
|
38
|
+
2.x.
|
39
|
+
|
40
|
+
* Fixing array tests in jruby - Dan McClain
|
41
|
+
* Removes encoding patches from PostgreSQLAdapter - Dan McClain
|
42
|
+
* Update documentation to reflect changes in 0.3.0 - Fabian Schwahn
|
43
|
+
* Allow conversion of string/text columns to array - Valentino
|
44
|
+
* Fix link to github issues in readme - Carlos Antonio da Silva
|
45
|
+
|
1
46
|
## 0.4.0
|
2
47
|
* Adds support for (limited) support for PostgreSQL ranges - Dan McClain
|
3
48
|
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@ Adds missing native PostgreSQL data types to ActiveRecord and convenient queryin
|
|
4
4
|
|
5
5
|
[](http://travis-ci.org/dockyard/postgres_ext)
|
6
6
|
[](https://codeclimate.com/github/dockyard/postgres_ext)
|
7
|
+
[](http://badge.fury.io/rb/postgres_ext)
|
7
8
|
|
8
9
|
## Looking for help? ##
|
9
10
|
|
@@ -39,6 +40,18 @@ Where are the datatypes from PostgresExt 1.x? ActiveRecord 4.x includes
|
|
39
40
|
all the data types that PostgresExt added to ActiveRecord 3.2.x. We'll
|
40
41
|
be adding more datatypes as we come across them.
|
41
42
|
|
43
|
+
## Developing
|
44
|
+
|
45
|
+
To work on postgres\_ext locally, follow these steps:
|
46
|
+
|
47
|
+
1. Run `bundle install`, this will install all the development
|
48
|
+
dependencies
|
49
|
+
2. Run `rake setup`, this will set up the `.env` file necessary to run
|
50
|
+
the tests and set up the database
|
51
|
+
3. Run `rake db:create`, this will create the test database
|
52
|
+
4. Run `rake db:migrate`, this will set up the database tables required
|
53
|
+
by the test
|
54
|
+
|
42
55
|
## Authors
|
43
56
|
|
44
57
|
Dan McClain [twitter](http://twitter.com/_danmcclain) [github](http://github.com/danmcclain)
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ begin
|
|
4
4
|
rescue LoadError
|
5
5
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
6
|
end
|
7
|
+
|
7
8
|
begin
|
8
9
|
require 'rdoc/task'
|
9
10
|
rescue LoadError
|
@@ -20,14 +21,89 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
20
21
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
22
|
end
|
22
23
|
|
23
|
-
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
-
load 'rails/tasks/engine.rake'
|
25
|
-
|
26
24
|
Bundler::GemHelper.install_tasks
|
27
25
|
|
28
|
-
require '
|
29
|
-
|
30
|
-
|
26
|
+
require 'rake/testtask'
|
27
|
+
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
29
|
+
t.libs << 'lib'
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
task :default => :test
|
36
|
+
|
37
|
+
task :setup do
|
38
|
+
if File.exist?('.env')
|
39
|
+
puts 'This will overwrite your existing .env file'
|
40
|
+
end
|
41
|
+
print 'Enter your database name: [postgres_ext_test] '
|
42
|
+
db_name = STDIN.gets.chomp
|
43
|
+
print 'Enter your database user: [] '
|
44
|
+
db_user = STDIN.gets.chomp
|
45
|
+
print 'Enter your database password: [] '
|
46
|
+
db_password = STDIN.gets.chomp
|
47
|
+
print 'Enter your database server: [localhost] '
|
48
|
+
db_server = STDIN.gets.chomp
|
49
|
+
|
50
|
+
db_name = 'postgres_ext_test' if db_name.empty?
|
51
|
+
db_password = ":#{db_password}" unless db_password.empty?
|
52
|
+
db_server = 'localhost' if db_server.empty?
|
53
|
+
|
54
|
+
db_server = "@#{db_server}" unless db_user.empty?
|
55
|
+
|
56
|
+
env_path = File.expand_path('./.env')
|
57
|
+
File.open(env_path, 'w') do |file|
|
58
|
+
file.puts "DATABASE_NAME=#{db_name}"
|
59
|
+
file.puts "DATABASE_URL=\"postgres://#{db_user}#{db_password}#{db_server}/#{db_name}\""
|
60
|
+
end
|
61
|
+
|
62
|
+
puts '.env file saved'
|
31
63
|
end
|
32
64
|
|
33
|
-
|
65
|
+
namespace :db do
|
66
|
+
task :load_db_settings do
|
67
|
+
require 'active_record'
|
68
|
+
unless ENV['DATABASE_URL']
|
69
|
+
require 'dotenv'
|
70
|
+
Dotenv.load
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
task :drop => :load_db_settings do
|
75
|
+
%x{ dropdb #{ENV['DATABASE_NAME']} }
|
76
|
+
end
|
77
|
+
|
78
|
+
task :create => :load_db_settings do
|
79
|
+
%x{ createdb #{ENV['DATABASE_NAME']} }
|
80
|
+
end
|
81
|
+
|
82
|
+
task :migrate => :load_db_settings do
|
83
|
+
ActiveRecord::Base.establish_connection
|
84
|
+
|
85
|
+
ActiveRecord::Base.connection.create_table :people, force: true do |t|
|
86
|
+
t.inet "ip"
|
87
|
+
t.cidr "subnet"
|
88
|
+
t.integer "tag_ids", array: true
|
89
|
+
t.string "tags", array: true
|
90
|
+
t.integer "lucky_number"
|
91
|
+
t.datetime "created_at"
|
92
|
+
t.datetime "updated_at"
|
93
|
+
end
|
94
|
+
|
95
|
+
ActiveRecord::Base.connection.create_table :people_tags, force: true do |t|
|
96
|
+
t.integer "person_id"
|
97
|
+
t.integer "tag_id"
|
98
|
+
end
|
99
|
+
|
100
|
+
ActiveRecord::Base.connection.create_table :tags, force: true do |t|
|
101
|
+
t.integer "person_id"
|
102
|
+
t.string "categories", array: true
|
103
|
+
t.datetime "created_at"
|
104
|
+
t.datetime "updated_at"
|
105
|
+
end
|
106
|
+
|
107
|
+
puts 'Database migrated'
|
108
|
+
end
|
109
|
+
end
|
data/docs/querying.md
CHANGED
@@ -1,3 +1,76 @@
|
|
1
|
+
# Common Table Expressions (CTEs)
|
2
|
+
|
3
|
+
Postgres\_ext adds CTE expression support to ActiveRecord via two
|
4
|
+
methods:
|
5
|
+
|
6
|
+
* [`Relation#with`](#with)
|
7
|
+
* [`Model.from_cte`](#from_cte)
|
8
|
+
|
9
|
+
## with
|
10
|
+
|
11
|
+
We can add CTEs to queries by chaining `#with` off a relation.
|
12
|
+
`Relation#with` accepts a hash, and will convert `Relation`s to the
|
13
|
+
proper SQL in the CTE.
|
14
|
+
|
15
|
+
Let's expand a `#with` call to it's resulting SQL code:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
Score.with(my_games: Game.where(id: 1)).joins('JOIN my_games ON scores.game_id = my_games.id')
|
19
|
+
```
|
20
|
+
|
21
|
+
The following will be generated when that relation is evaluated:
|
22
|
+
|
23
|
+
```SQL
|
24
|
+
WITH my_games AS (
|
25
|
+
SELECT games.*
|
26
|
+
FROM games
|
27
|
+
WHERE games.id = 1
|
28
|
+
)
|
29
|
+
SELECT *
|
30
|
+
FROM scores
|
31
|
+
JOIN my_games
|
32
|
+
ON scores.games_id = my_games.id
|
33
|
+
```
|
34
|
+
|
35
|
+
You can also do a recursive with:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
Graph.with.recursive(search_graph:
|
39
|
+
" SELECT g.id, g.link, g.data, 1 AS depth
|
40
|
+
FROM graph g
|
41
|
+
UNION ALL
|
42
|
+
SELECT g.id, g.link, g.data, sg.depth + 1
|
43
|
+
FROM graph g, search_graph sg
|
44
|
+
WHERE g.id = sg.link").from(:search_graph)
|
45
|
+
```
|
46
|
+
|
47
|
+
## from\_cte
|
48
|
+
|
49
|
+
`Model.from_cte` is similiar to `Model.find_by_sql`, taking the CTE
|
50
|
+
passed in, but allowing you to chain off of it further, instead of just
|
51
|
+
retrieving the results.
|
52
|
+
|
53
|
+
Take the following ActiveRecord call:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
Score.from_cte('scores_for_game', Score.where(game_id: 1)).where(user_id: 1)
|
57
|
+
```
|
58
|
+
|
59
|
+
The following SQL will be called:
|
60
|
+
|
61
|
+
```SQL
|
62
|
+
WITH scores_for_game AS (
|
63
|
+
SELECT *
|
64
|
+
FROM scores
|
65
|
+
WHERE game_id = 1
|
66
|
+
)
|
67
|
+
SELECT *
|
68
|
+
FROM scores_for_game
|
69
|
+
WHERE scores_for_game.user_id = 1
|
70
|
+
```
|
71
|
+
|
72
|
+
And will be converted to `Score` objects
|
73
|
+
|
1
74
|
# Querying PostgreSQL datatypes
|
2
75
|
|
3
76
|
* [Arrays](#arrays)
|
@@ -109,16 +182,13 @@ accompish this:
|
|
109
182
|
```ruby
|
110
183
|
user_arel = User.arel_table
|
111
184
|
|
112
|
-
any_tags_function = Arel::Nodes::NamedFunction.new('ANY', [user_arel[:tags]])
|
113
|
-
predicate = Arel::Nodes::Equality.new('test', any_tags_function)
|
114
|
-
|
115
185
|
# Execute the query
|
116
|
-
User.where(
|
186
|
+
User.where(user_arel[:tags].any('test'))
|
117
187
|
#=> SELECT \"users\".* FROM \"users\" WHERE 'test' = ANY(\"users\".\"tags\")
|
118
188
|
```
|
119
189
|
|
120
|
-
The ALL version of this same predicate can be generated by
|
121
|
-
|
190
|
+
The ALL version of this same predicate can be generated by swapping
|
191
|
+
`#any()` for `#all()`.
|
122
192
|
|
123
193
|
## INET/CIDR Queries
|
124
194
|
|
@@ -8,8 +8,8 @@ module ActiveRecord
|
|
8
8
|
case value
|
9
9
|
when Array
|
10
10
|
engine = attribute.relation.engine
|
11
|
-
column = engine.columns.detect{ |col| col.name == attribute.name }
|
12
|
-
if column.array
|
11
|
+
column = engine.columns.detect{ |col| col.name.to_s == attribute.name.to_s }
|
12
|
+
if column && column.array
|
13
13
|
attribute.eq(value)
|
14
14
|
else
|
15
15
|
values = value.to_a.map {|x| x.is_a?(Base) ? x.id : x}
|
@@ -67,6 +67,21 @@ module ActiveRecord
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# WithChain objects act as placeholder for queries in which #with does not have any parameter.
|
71
|
+
# In this case, #with must be chained with #recursive to return a new relation.
|
72
|
+
class WithChain
|
73
|
+
def initialize(scope)
|
74
|
+
@scope = scope
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a new relation expressing WITH RECURSIVE
|
78
|
+
def recursive(*args)
|
79
|
+
@scope.with_values += args
|
80
|
+
@scope.recursive_value = true
|
81
|
+
@scope
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
70
85
|
[:with].each do |name|
|
71
86
|
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
72
87
|
def #{name}_values # def select_values
|
@@ -80,7 +95,7 @@ module ActiveRecord
|
|
80
95
|
CODE
|
81
96
|
end
|
82
97
|
|
83
|
-
[:rank].each do |name|
|
98
|
+
[:rank, :recursive].each do |name|
|
84
99
|
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
85
100
|
def #{name}_value=(value) # def readonly_value=(value)
|
86
101
|
raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded
|
@@ -93,14 +108,23 @@ module ActiveRecord
|
|
93
108
|
CODE
|
94
109
|
end
|
95
110
|
|
96
|
-
def with(*
|
97
|
-
|
98
|
-
|
111
|
+
def with(opts = :chain, *rest)
|
112
|
+
if opts == :chain
|
113
|
+
WithChain.new(spawn)
|
114
|
+
elsif opts.blank?
|
115
|
+
self
|
116
|
+
else
|
117
|
+
spawn.with!(opts, *rest)
|
118
|
+
end
|
99
119
|
end
|
100
120
|
|
101
|
-
def with!(*
|
102
|
-
|
103
|
-
|
121
|
+
def with!(opts = :chain, *rest) # :nodoc:
|
122
|
+
if opts == :chain
|
123
|
+
WithChain.new(self)
|
124
|
+
else
|
125
|
+
self.with_values += [opts] + rest
|
126
|
+
self
|
127
|
+
end
|
104
128
|
end
|
105
129
|
|
106
130
|
def ranked(options = :order)
|
@@ -115,15 +139,16 @@ module ActiveRecord
|
|
115
139
|
def build_arel_with_extensions
|
116
140
|
arel = build_arel_without_extensions
|
117
141
|
|
118
|
-
build_with(arel
|
142
|
+
build_with(arel)
|
119
143
|
|
120
144
|
build_rank(arel, rank_value) if rank_value
|
121
145
|
|
122
146
|
arel
|
123
147
|
end
|
124
148
|
|
125
|
-
def build_with(arel
|
126
|
-
|
149
|
+
def build_with(arel)
|
150
|
+
visitor = arel.engine.connection.visitor
|
151
|
+
with_statements = with_values.flat_map do |with_value|
|
127
152
|
case with_value
|
128
153
|
when String
|
129
154
|
with_value
|
@@ -134,12 +159,20 @@ module ActiveRecord
|
|
134
159
|
select = Arel::SqlLiteral.new "(#{expression})"
|
135
160
|
when ActiveRecord::Relation
|
136
161
|
select = Arel::SqlLiteral.new "(#{expression.to_sql})"
|
162
|
+
when Arel::SelectManager
|
163
|
+
select = Arel::SqlLiteral.new visitor.accept(expression)
|
137
164
|
end
|
138
165
|
as = Arel::Nodes::As.new Arel::SqlLiteral.new(name.to_s), select
|
139
166
|
end
|
140
167
|
end
|
141
168
|
end
|
142
|
-
|
169
|
+
unless with_statements.empty?
|
170
|
+
if recursive_value
|
171
|
+
arel.with :recursive, with_statements
|
172
|
+
else
|
173
|
+
arel.with with_statements
|
174
|
+
end
|
175
|
+
end
|
143
176
|
end
|
144
177
|
|
145
178
|
def build_rank(arel, rank_window_options)
|