sequel 5.6.0 → 5.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +30 -5099
  3. data/Rakefile +1 -1
  4. data/doc/opening_databases.rdoc +0 -2
  5. data/doc/postgresql.rdoc +31 -0
  6. data/doc/querying.rdoc +2 -2
  7. data/doc/release_notes/5.7.0.txt +108 -0
  8. data/doc/testing.rdoc +1 -0
  9. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  10. data/lib/sequel/adapters/jdbc/oracle.rb +11 -0
  11. data/lib/sequel/adapters/postgres.rb +1 -0
  12. data/lib/sequel/adapters/shared/postgres.rb +117 -13
  13. data/lib/sequel/connection_pool/sharded_threaded.rb +7 -6
  14. data/lib/sequel/connection_pool/threaded.rb +6 -6
  15. data/lib/sequel/core.rb +20 -0
  16. data/lib/sequel/database/logging.rb +3 -2
  17. data/lib/sequel/database/schema_generator.rb +1 -2
  18. data/lib/sequel/dataset/actions.rb +15 -5
  19. data/lib/sequel/extensions/connection_expiration.rb +3 -3
  20. data/lib/sequel/extensions/connection_validator.rb +3 -3
  21. data/lib/sequel/extensions/integer64.rb +30 -0
  22. data/lib/sequel/extensions/migration.rb +2 -3
  23. data/lib/sequel/plugins/pg_array_associations.rb +5 -3
  24. data/lib/sequel/plugins/validate_associated.rb +18 -0
  25. data/lib/sequel/version.rb +1 -1
  26. data/spec/adapters/mssql_spec.rb +6 -6
  27. data/spec/adapters/mysql_spec.rb +1 -1
  28. data/spec/adapters/oracle_spec.rb +15 -1
  29. data/spec/adapters/postgres_spec.rb +78 -1
  30. data/spec/adapters/spec_helper.rb +3 -1
  31. data/spec/bin_spec.rb +1 -0
  32. data/spec/core/dataset_spec.rb +10 -0
  33. data/spec/extensions/integer64_spec.rb +22 -0
  34. data/spec/extensions/pg_array_associations_spec.rb +14 -2
  35. data/spec/extensions/spec_helper.rb +1 -0
  36. data/spec/integration/associations_test.rb +4 -4
  37. data/spec/integration/dataset_test.rb +2 -0
  38. data/spec/integration/spec_helper.rb +5 -11
  39. data/spec/model/spec_helper.rb +1 -0
  40. metadata +35 -165
  41. data/doc/release_notes/1.0.txt +0 -38
  42. data/doc/release_notes/1.1.txt +0 -143
  43. data/doc/release_notes/1.3.txt +0 -101
  44. data/doc/release_notes/1.4.0.txt +0 -53
  45. data/doc/release_notes/1.5.0.txt +0 -155
  46. data/doc/release_notes/2.0.0.txt +0 -298
  47. data/doc/release_notes/2.1.0.txt +0 -271
  48. data/doc/release_notes/2.10.0.txt +0 -328
  49. data/doc/release_notes/2.11.0.txt +0 -215
  50. data/doc/release_notes/2.12.0.txt +0 -534
  51. data/doc/release_notes/2.2.0.txt +0 -253
  52. data/doc/release_notes/2.3.0.txt +0 -88
  53. data/doc/release_notes/2.4.0.txt +0 -106
  54. data/doc/release_notes/2.5.0.txt +0 -137
  55. data/doc/release_notes/2.6.0.txt +0 -157
  56. data/doc/release_notes/2.7.0.txt +0 -166
  57. data/doc/release_notes/2.8.0.txt +0 -171
  58. data/doc/release_notes/2.9.0.txt +0 -97
  59. data/doc/release_notes/3.0.0.txt +0 -221
  60. data/doc/release_notes/3.1.0.txt +0 -406
  61. data/doc/release_notes/3.10.0.txt +0 -286
  62. data/doc/release_notes/3.11.0.txt +0 -254
  63. data/doc/release_notes/3.12.0.txt +0 -304
  64. data/doc/release_notes/3.13.0.txt +0 -210
  65. data/doc/release_notes/3.14.0.txt +0 -118
  66. data/doc/release_notes/3.15.0.txt +0 -78
  67. data/doc/release_notes/3.16.0.txt +0 -45
  68. data/doc/release_notes/3.17.0.txt +0 -58
  69. data/doc/release_notes/3.18.0.txt +0 -120
  70. data/doc/release_notes/3.19.0.txt +0 -67
  71. data/doc/release_notes/3.2.0.txt +0 -268
  72. data/doc/release_notes/3.20.0.txt +0 -41
  73. data/doc/release_notes/3.21.0.txt +0 -87
  74. data/doc/release_notes/3.22.0.txt +0 -39
  75. data/doc/release_notes/3.23.0.txt +0 -172
  76. data/doc/release_notes/3.24.0.txt +0 -420
  77. data/doc/release_notes/3.25.0.txt +0 -88
  78. data/doc/release_notes/3.26.0.txt +0 -88
  79. data/doc/release_notes/3.27.0.txt +0 -82
  80. data/doc/release_notes/3.28.0.txt +0 -304
  81. data/doc/release_notes/3.29.0.txt +0 -459
  82. data/doc/release_notes/3.3.0.txt +0 -192
  83. data/doc/release_notes/3.30.0.txt +0 -135
  84. data/doc/release_notes/3.31.0.txt +0 -146
  85. data/doc/release_notes/3.32.0.txt +0 -202
  86. data/doc/release_notes/3.33.0.txt +0 -157
  87. data/doc/release_notes/3.34.0.txt +0 -671
  88. data/doc/release_notes/3.35.0.txt +0 -144
  89. data/doc/release_notes/3.36.0.txt +0 -245
  90. data/doc/release_notes/3.37.0.txt +0 -338
  91. data/doc/release_notes/3.38.0.txt +0 -234
  92. data/doc/release_notes/3.39.0.txt +0 -237
  93. data/doc/release_notes/3.4.0.txt +0 -325
  94. data/doc/release_notes/3.40.0.txt +0 -73
  95. data/doc/release_notes/3.41.0.txt +0 -155
  96. data/doc/release_notes/3.42.0.txt +0 -74
  97. data/doc/release_notes/3.43.0.txt +0 -105
  98. data/doc/release_notes/3.44.0.txt +0 -152
  99. data/doc/release_notes/3.45.0.txt +0 -179
  100. data/doc/release_notes/3.46.0.txt +0 -122
  101. data/doc/release_notes/3.47.0.txt +0 -270
  102. data/doc/release_notes/3.48.0.txt +0 -477
  103. data/doc/release_notes/3.5.0.txt +0 -510
  104. data/doc/release_notes/3.6.0.txt +0 -366
  105. data/doc/release_notes/3.7.0.txt +0 -179
  106. data/doc/release_notes/3.8.0.txt +0 -151
  107. 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|
@@ -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
 
@@ -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
@@ -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, = Artist.get([:id, :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.
@@ -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 => :integer, :identity=>true, :start_with=>1}
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
@@ -45,6 +45,7 @@ module Sequel
45
45
  DISCONNECT_ERROR_CLASSES.freeze
46
46
 
47
47
  disconnect_errors = [
48
+ 'ERROR: cached plan must not change result type',
48
49
  'could not receive data from server',
49
50
  'no connection to the server',
50
51
  'connection not open',
@@ -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
- {:primary_key => true, :serial => true, :type=>Integer}
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
- @server_version = synchronize(server) do |conn|
538
- (conn.server_version rescue nil) if conn.respond_to?(:server_version)
539
- end
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] =~ /\Anextval/io)
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
- time = Time.now
188
+ timeout = @timeout
189
+ timer = Sequel.start_timer
189
190
 
190
191
  sync do
191
- @waiters[server].wait(@mutex, @timeout)
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
- deadline ||= time + @timeout
199
- current_time = Time.now
200
- raise_pool_timeout(current_time - time, server) if current_time > deadline
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, deadline - current_time)
206
+ @waiters[server].wait(@mutex, timeout - elapsed)
206
207
  if conn = next_available(server)
207
208
  return(allocated(server)[thread] = conn)
208
209
  end