postgres_ext 2.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://secure.travis-ci.org/dockyard/postgres_ext.png?branch=master)](http://travis-ci.org/dockyard/postgres_ext)
|
6
6
|
[![Code Climate](https://codeclimate.com/github/dockyard/postgres_ext.png)](https://codeclimate.com/github/dockyard/postgres_ext)
|
7
|
+
[![Gem Version](https://badge.fury.io/rb/postgres_ext.png)](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)
|