sequel 5.6.0 → 5.7.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/CHANGELOG +30 -5099
- data/Rakefile +1 -1
- data/doc/opening_databases.rdoc +0 -2
- data/doc/postgresql.rdoc +31 -0
- data/doc/querying.rdoc +2 -2
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/testing.rdoc +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +11 -0
- data/lib/sequel/adapters/postgres.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +117 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +7 -6
- data/lib/sequel/connection_pool/threaded.rb +6 -6
- data/lib/sequel/core.rb +20 -0
- data/lib/sequel/database/logging.rb +3 -2
- data/lib/sequel/database/schema_generator.rb +1 -2
- data/lib/sequel/dataset/actions.rb +15 -5
- data/lib/sequel/extensions/connection_expiration.rb +3 -3
- data/lib/sequel/extensions/connection_validator.rb +3 -3
- data/lib/sequel/extensions/integer64.rb +30 -0
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/plugins/pg_array_associations.rb +5 -3
- data/lib/sequel/plugins/validate_associated.rb +18 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +6 -6
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +15 -1
- data/spec/adapters/postgres_spec.rb +78 -1
- data/spec/adapters/spec_helper.rb +3 -1
- data/spec/bin_spec.rb +1 -0
- data/spec/core/dataset_spec.rb +10 -0
- data/spec/extensions/integer64_spec.rb +22 -0
- data/spec/extensions/pg_array_associations_spec.rb +14 -2
- data/spec/extensions/spec_helper.rb +1 -0
- data/spec/integration/associations_test.rb +4 -4
- data/spec/integration/dataset_test.rb +2 -0
- data/spec/integration/spec_helper.rb +5 -11
- data/spec/model/spec_helper.rb +1 -0
- metadata +35 -165
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
data/Rakefile
CHANGED
|
@@ -49,7 +49,7 @@ task :website_rdoc=>[:website_rdoc_main, :website_rdoc_adapters, :website_rdoc_p
|
|
|
49
49
|
RDoc::Task.new(:website_rdoc_main) do |rdoc|
|
|
50
50
|
rdoc.rdoc_dir = "www/public/rdoc"
|
|
51
51
|
rdoc.options += RDOC_OPTS + %w'--no-ignore-invalid'
|
|
52
|
-
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb"
|
|
52
|
+
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG doc/CHANGELOG.old MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb"
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
RDoc::Task.new(:website_rdoc_adapters) do |rdoc|
|
data/doc/opening_databases.rdoc
CHANGED
|
@@ -230,8 +230,6 @@ The following additional options are supported:
|
|
|
230
230
|
There are a few issues with specific jdbc driver gems:
|
|
231
231
|
|
|
232
232
|
jdbc-h2 :: jdbc-h2 versions greater than 1.3.175 have issues with ORDER BY not working correctly in some cases.
|
|
233
|
-
jdbc-postgres :: jdbc-postgres 9.4.1204 has issues using PostgreSQL-specific types in bound variables.
|
|
234
|
-
Use jdbc-postgres 9.4.1200 or below.
|
|
235
233
|
|
|
236
234
|
=== mysql
|
|
237
235
|
|
data/doc/postgresql.rdoc
CHANGED
|
@@ -139,6 +139,21 @@ allows you do create an unlogged table by specifying the <tt>unlogged: true</tt>
|
|
|
139
139
|
DB.create_table(:table, unlogged: true){Integer :i}
|
|
140
140
|
# CREATE UNLOGGED TABLE "table" ("i" integer)
|
|
141
141
|
|
|
142
|
+
=== Creating Identity Columns
|
|
143
|
+
|
|
144
|
+
You can use the +:identity+ option when creating columns to mark them as identity columns.
|
|
145
|
+
Identity columns are tied to a sequence for the default value. You can still override the
|
|
146
|
+
default value for the column when inserting:
|
|
147
|
+
|
|
148
|
+
DB.create_table(:table){Integer :id, identity: true}
|
|
149
|
+
# CREATE TABLE "table" ("id" integer GENERATED BY DEFAULT AS IDENTITY)
|
|
150
|
+
|
|
151
|
+
If you want to disallow using a user provided value when inserting, you can mark the
|
|
152
|
+
identity column using <tt>identity: :always</tt>:
|
|
153
|
+
|
|
154
|
+
DB.create_table(:table){Integer :id, identity: :always}
|
|
155
|
+
# CREATE TABLE "table" ("id" integer GENERATED ALWAYS AS IDENTITY)
|
|
156
|
+
|
|
142
157
|
=== Creating/Dropping Schemas, Languages, Functions, and Triggers
|
|
143
158
|
|
|
144
159
|
Sequel has built in support for creating and dropping PostgreSQL schemas, procedural languages, functions, and triggers:
|
|
@@ -255,6 +270,22 @@ conditions, the constraint violation will be ignored, but the row will not be up
|
|
|
255
270
|
# ON CONFLICT ON CONSTRAINT table_a_uidx
|
|
256
271
|
# DO UPDATE SET b = excluded.b WHERE (table.status_id = 1)
|
|
257
272
|
|
|
273
|
+
=== INSERT OVERRIDING SYSTEM|USER VALUE Support
|
|
274
|
+
|
|
275
|
+
PostgreSQL 10+ supports identity columns, which are designed to replace the serial
|
|
276
|
+
columns previously used for autoincrementing primary keys. You can use
|
|
277
|
+
Dataset#overriding_system_value and Dataset#overriding_user_value to use this new
|
|
278
|
+
syntax:
|
|
279
|
+
|
|
280
|
+
DB.create_table(:table){primary_key :id}
|
|
281
|
+
# Ignore the given value for id, using the identity's sequence value
|
|
282
|
+
DB[:table].overriding_user_value.insert(:id=>1)
|
|
283
|
+
|
|
284
|
+
DB.create_table(:table){primary_key :id, :identity=>:always}
|
|
285
|
+
# Force the use of the given value for id, because otherwise the insert will
|
|
286
|
+
# raise an error, since GENERATED ALWAYS was using when creating the column.
|
|
287
|
+
DB[:table].overriding_system_value.insert(:id=>1)
|
|
288
|
+
|
|
258
289
|
=== Distinct On Specific Columns
|
|
259
290
|
|
|
260
291
|
Sequel allows passing columns to <tt>Dataset#distinct</tt>, which will make the dataset return
|
data/doc/querying.rdoc
CHANGED
|
@@ -111,8 +111,8 @@ you want:
|
|
|
111
111
|
If you want the value for multiple columns, you can pass an array to
|
|
112
112
|
<tt>Sequel::Dataset#get</tt>:
|
|
113
113
|
|
|
114
|
-
artist_id, artist_name
|
|
115
|
-
# SELECT name FROM artists LIMIT 1
|
|
114
|
+
artist_id, artist_name = Artist.get([:id, :name])
|
|
115
|
+
# SELECT id, name FROM artists LIMIT 1
|
|
116
116
|
# => [1, "YJM"]
|
|
117
117
|
|
|
118
118
|
=== Retrieving Multiple Objects
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* An integer64 extension has been added, which treats the Integer
|
|
4
|
+
class as a generic 64-bit integer type. Sequel's default behavior
|
|
5
|
+
for Integer is to use the integer type, which on most databases
|
|
6
|
+
is a 32-bit type.
|
|
7
|
+
|
|
8
|
+
This affects all internal use of the Integer class as a generic
|
|
9
|
+
database type, so that methods like primary_key and foreign_key
|
|
10
|
+
also default to using a 64-bit integer type when using this
|
|
11
|
+
extension.
|
|
12
|
+
|
|
13
|
+
* When using PostgreSQL 10+, you can use the :identity option when
|
|
14
|
+
creating columns to create identity columns:
|
|
15
|
+
|
|
16
|
+
DB.create_table(:table){Integer :id, identity: true}
|
|
17
|
+
# CREATE TABLE "table" ("id" integer GENERATED BY DEFAULT AS IDENTITY)
|
|
18
|
+
|
|
19
|
+
If you want to disallow using a user provided value when inserting,
|
|
20
|
+
or updating you can use a value of :always:
|
|
21
|
+
|
|
22
|
+
DB.create_table(:table){Integer :id, identity: :always}
|
|
23
|
+
# CREATE TABLE "table" ("id" integer GENERATED ALWAYS AS IDENTITY)
|
|
24
|
+
|
|
25
|
+
* Database#convert_serial_to_identity has been added on PostgreSQL 10.2+.
|
|
26
|
+
This method can convert existing serial columns to identity columns
|
|
27
|
+
in most cases, but it currently requires superuser permissions as it
|
|
28
|
+
modifies the system tables directly.
|
|
29
|
+
|
|
30
|
+
* Dataset#overriding_system_value and #overriding_user_value are
|
|
31
|
+
now supported on PostgreSQL to work with identity columns. You can
|
|
32
|
+
use #overriding_system_value to force the use of a user provided
|
|
33
|
+
value for identity columns that are GENERATED ALWAYS, and you can
|
|
34
|
+
use #overriding_user_value to ignore any user value for identity
|
|
35
|
+
columns and always use the next entry in the sequence.
|
|
36
|
+
|
|
37
|
+
= Other Improvements
|
|
38
|
+
|
|
39
|
+
* On PostgreSQL 10.2+, identity columns are now used instead of serial
|
|
40
|
+
columns as the default for auto incrementing primary keys:
|
|
41
|
+
|
|
42
|
+
DB.create_table(:table){primary_key :id}
|
|
43
|
+
|
|
44
|
+
# Sequel 5.7.0+ and PostgreSQL 10.2+
|
|
45
|
+
# CREATE TABLE "table" ("id" integer
|
|
46
|
+
# GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY)
|
|
47
|
+
|
|
48
|
+
# Older Sequel version or older PostgreSQL version
|
|
49
|
+
# CREATE TABLE "table" ("id" serial PRIMARY KEY)
|
|
50
|
+
|
|
51
|
+
Identity columns fix many issues that serial columns have, in
|
|
52
|
+
addition to being the SQL standard way to support auto incrementing
|
|
53
|
+
columns.
|
|
54
|
+
|
|
55
|
+
* PostgreSQL identity columns are now correctly recognized and the
|
|
56
|
+
:auto_increment schema entry is now populated for them.
|
|
57
|
+
|
|
58
|
+
* Dataset#with_sql_{all,each,first,single_value} now use a cached
|
|
59
|
+
dataset to avoid clobbering the current dataset's columns.
|
|
60
|
+
Previously, the clobbering of the current dataset's columns was
|
|
61
|
+
documented and the method warned against using SQL with
|
|
62
|
+
different columns. These methods are now safe to use in such
|
|
63
|
+
cases, but will not have the same performance advantages if the
|
|
64
|
+
current dataset is not cached.
|
|
65
|
+
|
|
66
|
+
* On ruby 2.1+, Sequel now uses Process::CLOCK_MONOTONIC when
|
|
67
|
+
performing elapsed time calculations so that it is not affected by
|
|
68
|
+
modifications to the system's time.
|
|
69
|
+
|
|
70
|
+
* In the postgres adapter, prepared statement errors related to
|
|
71
|
+
changing types are now treated as disconnect errors. While they
|
|
72
|
+
are not technically disconnect errors, treating them as such
|
|
73
|
+
will in general reduce the total number of exceptions generated
|
|
74
|
+
from 1 per affected statement per connection to 1 per
|
|
75
|
+
connection.
|
|
76
|
+
|
|
77
|
+
* In the pg_array_associations plugin, the array_type for
|
|
78
|
+
pg_array_to_many and many_to_pg_array association reflections is
|
|
79
|
+
now always the scalar type for the array (e.g. integer). Previously,
|
|
80
|
+
the array type (e.g. integer[]) was used in some cases. This didn't
|
|
81
|
+
previously result in issues as PostgreSQL considers integer[][] the
|
|
82
|
+
same type as integer[].
|
|
83
|
+
|
|
84
|
+
* In the pg_array_associations plugin, the many_to_pg_array
|
|
85
|
+
association remove_all_* method now uses the appropriate cast to
|
|
86
|
+
work for non-integer array types such as bigint[].
|
|
87
|
+
|
|
88
|
+
* Database#server_version on PostgreSQL 10.1+ now works correctly
|
|
89
|
+
when the connection does not support the server_version method.
|
|
90
|
+
Now the server_version_num database setting is always used to
|
|
91
|
+
ensure consistent behavior across adapters.
|
|
92
|
+
|
|
93
|
+
* In the jdbc/oracle adapter, temporary clobs are now manually
|
|
94
|
+
freed to prevent a memory leak, in line with the Oracle JDBC
|
|
95
|
+
driver recommendations.
|
|
96
|
+
|
|
97
|
+
* The Sequel <4 release notes and changelog are no longer shipped
|
|
98
|
+
with the gem, decreasing the size of the gem by 20%.
|
|
99
|
+
|
|
100
|
+
= Backwards Compatibility
|
|
101
|
+
|
|
102
|
+
* The switch to using identity columns instead of serial columns
|
|
103
|
+
by default on PostgreSQL 10.2+ may break backwards compatibilty
|
|
104
|
+
in some situations, such as code that relies on what are generally
|
|
105
|
+
considered bugs in serial columns, such as CREATE TABLE LIKE
|
|
106
|
+
using the same sequence for the column in both the existing table
|
|
107
|
+
and the new table, or that dropping the default value for the
|
|
108
|
+
column does not drop the related sequence.
|
data/doc/testing.rdoc
CHANGED
|
@@ -159,6 +159,7 @@ SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
|
|
|
159
159
|
SEQUEL_INDEX_CACHING :: Use the index_caching extension when running the specs
|
|
160
160
|
SEQUEL_FREEZE_DATABASE :: Freeze the database before running the integration specs
|
|
161
161
|
SEQUEL_IDENTIFIER_MANGLING :: Use the identifier_mangling extension when running the specs
|
|
162
|
+
SEQUEL_INTEGER64 :: Use the integer64 extension when running the adapter or integration specs
|
|
162
163
|
SEQUEL_MODEL_PREPARED_STATEMENTS :: Use the prepared_statements plugin when running the specs
|
|
163
164
|
SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
|
|
164
165
|
SEQUEL_NO_CHECK_SQLS :: Don't check for specific SQL syntax when running the specs
|
|
@@ -36,7 +36,7 @@ module Sequel
|
|
|
36
36
|
|
|
37
37
|
# Derby uses an IDENTITY sequence for autoincrementing columns.
|
|
38
38
|
def serial_primary_key_options
|
|
39
|
-
{:primary_key => true, :type =>
|
|
39
|
+
{:primary_key => true, :type => Integer, :identity=>true, :start_with=>1}
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# The SVN version of the database.
|
|
@@ -28,6 +28,13 @@ module Sequel
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
def self.OracleClob(r, i)
|
|
32
|
+
return unless clob = r.getClob(i)
|
|
33
|
+
str = clob.getSubString(1, clob.length)
|
|
34
|
+
clob.freeTemporary if clob.isTemporary
|
|
35
|
+
str
|
|
36
|
+
end
|
|
37
|
+
|
|
31
38
|
module DatabaseMethods
|
|
32
39
|
include Sequel::Oracle::DatabaseMethods
|
|
33
40
|
include Sequel::JDBC::Transactions
|
|
@@ -104,6 +111,7 @@ module Sequel
|
|
|
104
111
|
def setup_type_convertor_map
|
|
105
112
|
super
|
|
106
113
|
@type_convertor_map[:OracleDecimal] = Oracle.method(:OracleDecimal)
|
|
114
|
+
@type_convertor_map[:OracleClob] = Oracle.method(:OracleClob)
|
|
107
115
|
end
|
|
108
116
|
end
|
|
109
117
|
|
|
@@ -112,6 +120,7 @@ module Sequel
|
|
|
112
120
|
|
|
113
121
|
NUMERIC_TYPE = Java::JavaSQL::Types::NUMERIC
|
|
114
122
|
TIMESTAMP_TYPE = Java::JavaSQL::Types::TIMESTAMP
|
|
123
|
+
CLOB_TYPE = Java::JavaSQL::Types::CLOB
|
|
115
124
|
TIMESTAMPTZ_TYPES = [Java::oracle.jdbc.OracleTypes::TIMESTAMPTZ, Java::oracle.jdbc.OracleTypes::TIMESTAMPLTZ].freeze
|
|
116
125
|
|
|
117
126
|
def type_convertor(map, meta, type, i)
|
|
@@ -124,6 +133,8 @@ module Sequel
|
|
|
124
133
|
end
|
|
125
134
|
when *TIMESTAMPTZ_TYPES
|
|
126
135
|
map[TIMESTAMP_TYPE]
|
|
136
|
+
when CLOB_TYPE
|
|
137
|
+
map[:OracleClob]
|
|
127
138
|
else
|
|
128
139
|
super
|
|
129
140
|
end
|
|
@@ -213,6 +213,76 @@ module Sequel
|
|
|
213
213
|
run("COMMIT PREPARED #{literal(transaction_id)}", opts)
|
|
214
214
|
end
|
|
215
215
|
|
|
216
|
+
# Convert the first primary key column in the +table+ from being a serial column to being an identity column.
|
|
217
|
+
# If the column is already an identity column, assume it was already converted and make no changes.
|
|
218
|
+
#
|
|
219
|
+
# Only supported on PostgreSQL 10.2+, since on those versions Sequel will use identity columns
|
|
220
|
+
# instead of serial columns for auto incrementing primary keys. Only supported when running as
|
|
221
|
+
# a superuser, since regular users cannot modify system tables, and there is no way to keep an
|
|
222
|
+
# existing sequence when changing an existing column to be an identity column.
|
|
223
|
+
#
|
|
224
|
+
# This method can raise an exception in at least the following cases where it may otherwise succeed
|
|
225
|
+
# (there may be additional cases not listed here):
|
|
226
|
+
#
|
|
227
|
+
# * The serial column was added after table creation using PostgreSQL <7.3
|
|
228
|
+
# * A regular index also exists on the column (such an index can probably be dropped as the
|
|
229
|
+
# primary key index should suffice)
|
|
230
|
+
#
|
|
231
|
+
# Options:
|
|
232
|
+
# :column :: Specify the column to convert instead of using the first primary key column
|
|
233
|
+
# :server :: Run the SQL on the given server
|
|
234
|
+
def convert_serial_to_identity(table, opts=OPTS)
|
|
235
|
+
raise Error, "convert_serial_to_identity is only supported on PostgreSQL 10.2+" unless server_version >= 100002
|
|
236
|
+
|
|
237
|
+
server = opts[:server]
|
|
238
|
+
server_hash = server ? {:server=>server} : {}
|
|
239
|
+
ds = dataset
|
|
240
|
+
ds = ds.server(server) if server
|
|
241
|
+
|
|
242
|
+
raise Error, "convert_serial_to_identity requires superuser permissions" unless ds.get{current_setting('is_superuser')} == 'on'
|
|
243
|
+
|
|
244
|
+
table_oid = regclass_oid(table)
|
|
245
|
+
im = input_identifier_meth
|
|
246
|
+
unless column = im.call(opts[:column] || ((sch = schema(table).find{|col, sch| sch[:primary_key] && sch[:auto_increment]}) && sch[0]))
|
|
247
|
+
raise Error, "could not determine column to convert from serial to identity automatically"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
column_num = ds.from(:pg_attribute).
|
|
251
|
+
where(:attrelid=>table_oid, :attname=>column).
|
|
252
|
+
get(:attnum)
|
|
253
|
+
|
|
254
|
+
pg_class = Sequel.cast('pg_class', :regclass)
|
|
255
|
+
res = ds.from(:pg_depend).
|
|
256
|
+
where(:refclassid=>pg_class, :refobjid=>table_oid, :refobjsubid=>column_num, :classid=>pg_class, :objsubid=>0, :deptype=>%w'a i').
|
|
257
|
+
select_map([:objid, Sequel.as({:deptype=>'i'}, :v)])
|
|
258
|
+
|
|
259
|
+
case res.length
|
|
260
|
+
when 0
|
|
261
|
+
raise Error, "unable to find related sequence when converting serial to identity"
|
|
262
|
+
when 1
|
|
263
|
+
seq_oid, already_identity = res.first
|
|
264
|
+
else
|
|
265
|
+
raise Error, "more than one linked sequence found when converting serial to identity"
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
return if already_identity
|
|
269
|
+
|
|
270
|
+
transaction(server_hash) do
|
|
271
|
+
run("ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(column)} DROP DEFAULT", server_hash)
|
|
272
|
+
|
|
273
|
+
ds.from(:pg_depend).
|
|
274
|
+
where(:classid=>pg_class, :objid=>seq_oid, :objsubid=>0, :deptype=>'a').
|
|
275
|
+
update(:deptype=>'i')
|
|
276
|
+
|
|
277
|
+
ds.from(:pg_attribute).
|
|
278
|
+
where(:attrelid=>table_oid, :attname=>column).
|
|
279
|
+
update(:attidentity=>'d')
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
remove_cached_schema(table)
|
|
283
|
+
nil
|
|
284
|
+
end
|
|
285
|
+
|
|
216
286
|
# Creates the function in the database. Arguments:
|
|
217
287
|
# name :: name of the function to create
|
|
218
288
|
# definition :: string definition of the function, or object file for a dynamically loaded C function.
|
|
@@ -528,23 +598,16 @@ module Sequel
|
|
|
528
598
|
# PostgreSQL uses SERIAL psuedo-type instead of AUTOINCREMENT for
|
|
529
599
|
# managing incrementing primary keys.
|
|
530
600
|
def serial_primary_key_options
|
|
531
|
-
|
|
601
|
+
auto_increment_key = server_version >= 100002 ? :identity : :serial
|
|
602
|
+
{:primary_key => true, auto_increment_key => true, :type=>Integer}
|
|
532
603
|
end
|
|
533
604
|
|
|
534
605
|
# The version of the PostgreSQL server, used for determining capability.
|
|
535
606
|
def server_version(server=nil)
|
|
536
607
|
return @server_version if @server_version
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
unless @server_version
|
|
541
|
-
@server_version = if m = /PostgreSQL (\d+)\.(\d+)(?:(?:rc\d+)|\.(\d+))?/.match(fetch('SELECT version()').single_value)
|
|
542
|
-
(m[1].to_i * 10000) + (m[2].to_i * 100) + m[3].to_i
|
|
543
|
-
else
|
|
544
|
-
0
|
|
545
|
-
end
|
|
546
|
-
end
|
|
547
|
-
@server_version
|
|
608
|
+
ds = dataset
|
|
609
|
+
ds = ds.server(server) if server
|
|
610
|
+
@server_version ||= ds.with_sql("SELECT CAST(current_setting('server_version_num') AS integer) AS v").single_value rescue 0
|
|
548
611
|
end
|
|
549
612
|
|
|
550
613
|
# PostgreSQL supports CREATE TABLE IF NOT EXISTS on 9.1+
|
|
@@ -709,6 +772,17 @@ module Sequel
|
|
|
709
772
|
end
|
|
710
773
|
end
|
|
711
774
|
|
|
775
|
+
# Support identity columns, but only use the identity SQL syntax if no
|
|
776
|
+
# default value is given.
|
|
777
|
+
def column_definition_default_sql(sql, column)
|
|
778
|
+
super
|
|
779
|
+
if !column[:default] && (identity = column[:identity])
|
|
780
|
+
sql << " GENERATED "
|
|
781
|
+
sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
|
|
782
|
+
sql << " AS IDENTITY"
|
|
783
|
+
end
|
|
784
|
+
end
|
|
785
|
+
|
|
712
786
|
# Handle PostgreSQL specific default format.
|
|
713
787
|
def column_schema_normalize_default(default, type)
|
|
714
788
|
if m = /\A(?:B?('.*')::[^']+|\((-?\d+(?:\.\d+)?)\))\z/.match(default)
|
|
@@ -1115,6 +1189,11 @@ module Sequel
|
|
|
1115
1189
|
where{pg_attribute[:attnum] > 0}.
|
|
1116
1190
|
where{{pg_class[:oid]=>oid}}.
|
|
1117
1191
|
order{pg_attribute[:attnum]}
|
|
1192
|
+
|
|
1193
|
+
if server_version > 100000
|
|
1194
|
+
ds = ds.select_append{pg_attribute[:attidentity]}
|
|
1195
|
+
end
|
|
1196
|
+
|
|
1118
1197
|
ds.map do |row|
|
|
1119
1198
|
row[:default] = nil if blank_object?(row[:default])
|
|
1120
1199
|
if row[:base_oid]
|
|
@@ -1127,8 +1206,9 @@ module Sequel
|
|
|
1127
1206
|
row.delete(:db_base_type)
|
|
1128
1207
|
end
|
|
1129
1208
|
row[:type] = schema_column_type(row[:db_type])
|
|
1209
|
+
identity = row.delete(:attidentity)
|
|
1130
1210
|
if row[:primary_key]
|
|
1131
|
-
row[:auto_increment] = !!(row[:default] =~ /\
|
|
1211
|
+
row[:auto_increment] = !!(row[:default] =~ /\A(?:nextval)/i) || identity == 'a' || identity == 'd'
|
|
1132
1212
|
end
|
|
1133
1213
|
[m.call(row.delete(:name)), row]
|
|
1134
1214
|
end
|
|
@@ -1430,6 +1510,19 @@ module Sequel
|
|
|
1430
1510
|
nil
|
|
1431
1511
|
end
|
|
1432
1512
|
|
|
1513
|
+
# Use OVERRIDING USER VALUE for INSERT statements, so that identity columns
|
|
1514
|
+
# always use the user supplied value, and an error is not raised for identity
|
|
1515
|
+
# columns that are GENERATED ALWAYS.
|
|
1516
|
+
def overriding_system_value
|
|
1517
|
+
clone(:override=>:system)
|
|
1518
|
+
end
|
|
1519
|
+
|
|
1520
|
+
# Use OVERRIDING USER VALUE for INSERT statements, so that identity columns
|
|
1521
|
+
# always use the sequence value instead of the user supplied value.
|
|
1522
|
+
def overriding_user_value
|
|
1523
|
+
clone(:override=>:user)
|
|
1524
|
+
end
|
|
1525
|
+
|
|
1433
1526
|
def supports_cte?(type=:select)
|
|
1434
1527
|
if type == :select
|
|
1435
1528
|
server_version >= 80400
|
|
@@ -1626,6 +1719,17 @@ module Sequel
|
|
|
1626
1719
|
end
|
|
1627
1720
|
end
|
|
1628
1721
|
|
|
1722
|
+
# Support OVERRIDING SYSTEM|USER VALUE in insert statements
|
|
1723
|
+
def insert_values_sql(sql)
|
|
1724
|
+
case opts[:override]
|
|
1725
|
+
when :system
|
|
1726
|
+
sql << " OVERRIDING SYSTEM VALUE"
|
|
1727
|
+
when :user
|
|
1728
|
+
sql << " OVERRIDING USER VALUE"
|
|
1729
|
+
end
|
|
1730
|
+
super
|
|
1731
|
+
end
|
|
1732
|
+
|
|
1629
1733
|
# For multiple table support, PostgreSQL requires at least
|
|
1630
1734
|
# two from tables, with joins allowed.
|
|
1631
1735
|
def join_from_sql(type, sql)
|
|
@@ -185,24 +185,25 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
185
185
|
return conn
|
|
186
186
|
end
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
timeout = @timeout
|
|
189
|
+
timer = Sequel.start_timer
|
|
189
190
|
|
|
190
191
|
sync do
|
|
191
|
-
@waiters[server].wait(@mutex,
|
|
192
|
+
@waiters[server].wait(@mutex, timeout)
|
|
192
193
|
if conn = next_available(server)
|
|
193
194
|
return(allocated(server)[thread] = conn)
|
|
194
195
|
end
|
|
195
196
|
end
|
|
196
197
|
|
|
197
198
|
until conn = assign_connection(thread, server)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
elapsed = Sequel.elapsed_seconds_since(timer)
|
|
200
|
+
raise_pool_timeout(elapsed, server) if elapsed > timeout
|
|
201
|
+
|
|
201
202
|
# :nocov:
|
|
202
203
|
# It's difficult to get to this point, it can only happen if there is a race condition
|
|
203
204
|
# where a connection cannot be acquired even after the thread is signalled by the condition
|
|
204
205
|
sync do
|
|
205
|
-
@waiters[server].wait(@mutex,
|
|
206
|
+
@waiters[server].wait(@mutex, timeout - elapsed)
|
|
206
207
|
if conn = next_available(server)
|
|
207
208
|
return(allocated(server)[thread] = conn)
|
|
208
209
|
end
|