sequel 5.23.0 → 5.28.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +62 -0
  3. data/README.rdoc +1 -1
  4. data/doc/cheat_sheet.rdoc +1 -0
  5. data/doc/postgresql.rdoc +2 -2
  6. data/doc/release_notes/5.24.0.txt +56 -0
  7. data/doc/release_notes/5.25.0.txt +32 -0
  8. data/doc/release_notes/5.26.0.txt +35 -0
  9. data/doc/release_notes/5.27.0.txt +21 -0
  10. data/doc/release_notes/5.28.0.txt +16 -0
  11. data/doc/testing.rdoc +11 -6
  12. data/lib/sequel/adapters/jdbc.rb +7 -1
  13. data/lib/sequel/adapters/jdbc/postgresql.rb +7 -13
  14. data/lib/sequel/adapters/mysql2.rb +0 -1
  15. data/lib/sequel/adapters/shared/mssql.rb +4 -2
  16. data/lib/sequel/adapters/shared/postgres.rb +30 -7
  17. data/lib/sequel/adapters/shared/sqlite.rb +7 -2
  18. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  19. data/lib/sequel/database/logging.rb +7 -1
  20. data/lib/sequel/database/schema_generator.rb +11 -2
  21. data/lib/sequel/database/schema_methods.rb +2 -0
  22. data/lib/sequel/dataset/features.rb +6 -0
  23. data/lib/sequel/dataset/query.rb +15 -2
  24. data/lib/sequel/dataset/sql.rb +17 -4
  25. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  26. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  27. data/lib/sequel/extensions/pg_array_ops.rb +10 -6
  28. data/lib/sequel/extensions/pg_enum.rb +4 -1
  29. data/lib/sequel/extensions/pg_json.rb +1 -1
  30. data/lib/sequel/extensions/pg_json_ops.rb +124 -0
  31. data/lib/sequel/extensions/pg_range.rb +9 -0
  32. data/lib/sequel/extensions/sql_comments.rb +2 -2
  33. data/lib/sequel/model/base.rb +12 -5
  34. data/lib/sequel/plugins/association_multi_add_remove.rb +83 -0
  35. data/lib/sequel/plugins/caching.rb +3 -0
  36. data/lib/sequel/plugins/csv_serializer.rb +26 -9
  37. data/lib/sequel/plugins/dirty.rb +3 -9
  38. data/lib/sequel/plugins/nested_attributes.rb +7 -0
  39. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +89 -30
  40. data/lib/sequel/plugins/sharding.rb +11 -5
  41. data/lib/sequel/plugins/static_cache.rb +8 -3
  42. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  43. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  44. data/lib/sequel/sql.rb +4 -1
  45. data/lib/sequel/version.rb +1 -1
  46. data/spec/adapters/postgres_spec.rb +145 -17
  47. data/spec/adapters/sqlite_spec.rb +1 -1
  48. data/spec/bin_spec.rb +1 -1
  49. data/spec/core/database_spec.rb +20 -1
  50. data/spec/core/expression_filters_spec.rb +26 -7
  51. data/spec/core/schema_spec.rb +18 -0
  52. data/spec/core/spec_helper.rb +1 -1
  53. data/spec/core_extensions_spec.rb +1 -1
  54. data/spec/extensions/any_not_empty_spec.rb +23 -0
  55. data/spec/extensions/association_multi_add_remove_spec.rb +1041 -0
  56. data/spec/extensions/dirty_spec.rb +33 -0
  57. data/spec/extensions/exclude_or_null_spec.rb +15 -0
  58. data/spec/extensions/insert_conflict_spec.rb +26 -0
  59. data/spec/extensions/nested_attributes_spec.rb +48 -0
  60. data/spec/extensions/pg_array_ops_spec.rb +3 -3
  61. data/spec/extensions/pg_auto_constraint_validations_spec.rb +37 -0
  62. data/spec/extensions/pg_json_ops_spec.rb +67 -0
  63. data/spec/extensions/pg_range_spec.rb +35 -21
  64. data/spec/extensions/sharding_spec.rb +8 -0
  65. data/spec/extensions/spec_helper.rb +1 -1
  66. data/spec/extensions/static_cache_cache_spec.rb +35 -0
  67. data/spec/guards_helper.rb +1 -1
  68. data/spec/integration/dataset_test.rb +57 -17
  69. data/spec/integration/plugin_test.rb +1 -1
  70. data/spec/integration/schema_test.rb +9 -0
  71. data/spec/integration/spec_helper.rb +7 -1
  72. data/spec/model/spec_helper.rb +1 -1
  73. metadata +35 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfbb05761d35a09172ba5f1d4d7847ae58f152e50648e1fa63d4b284f1999ad5
4
- data.tar.gz: f7d4b90e74df4096171baba005935648519a0333aff77c5ba840bb634be8a4fd
3
+ metadata.gz: e206de897422ca8260c788bcfc20bcb154c9122dd17a12dc4b45ecdca023eb9a
4
+ data.tar.gz: 319df67cbb77d1b93d12cd0a1f429de0b674543ebd62b6407d40e1bd992e2352
5
5
  SHA512:
6
- metadata.gz: 345e4d6691206c1a353a2d103dc835b1fcaebed9f274717aa7356a3caf0da237aa14f168c659774261d02621934229966f9f75ad901eb663806359cb924df532
7
- data.tar.gz: 0db48e9f07d0dbd598742e85640b8dba965d27bf476e120bf1568e61f7fb19f513e8d9d82b8d69310d1bfde44333553490e14e354a69ce2623943297fe17649f
6
+ metadata.gz: a69c5b0bdfdb9c32503204b19d7dc18a7f78f7af7d46c44a7a4413ed4561c3ed3d0a796742045b158714a45f165957a0b9e5d6830bb110e53872a17a1ccb1ed8
7
+ data.tar.gz: 73a7df723afa66c70f72218e0327f10ef659a22614e5a4438d8fdc2ba16ec97d6e33213c4fd2ed08e806f2860f968786543015b34f38449093d71194aadb3655
data/CHANGELOG CHANGED
@@ -1,3 +1,65 @@
1
+ === 5.28.0 (2020-01-01)
2
+
3
+ * Warn when calling Sequel::JDBC::Postgres::Dataset#with_fetch_size (jeremyevans) (#1665)
4
+
5
+ * Add exclude_or_null extension, for filtering datasets where the condition is false or NULL (jeremyevans)
6
+
7
+ * Add any_not_empty extension, for making Dataset#any? without a block mean !empty? (jeremyevans)
8
+
9
+ === 5.27.0 (2019-12-01)
10
+
11
+ * Add Sequel::DEFAULT for a DEFAULT expression, useful for assigning to default values (jeremyevans)
12
+
13
+ * Make Postgres::ArrayOp#join in pg_array_ops extension work correctly on PostgreSQL <9.1 (jeremyevans)
14
+
15
+ * Make pg_enum extension work correctly on PostgreSQL 8.3-9.0 (jeremyevans)
16
+
17
+ * Emulate FILTER clause for aggregate functions using CASE on databases not supporting it directly (jeremyevans)
18
+
19
+ * Support ordering by NULLS FIRST/NULLS LAST without emulation on SQLite 3.30+ (jeremyevans)
20
+
21
+ === 5.26.0 (2019-11-01)
22
+
23
+ * Recognize two additional foreign key constraint violation codes on MySQL 8.0.13+ (rianmcguire) (#1657)
24
+
25
+ * Support table aliases for single-table INSERT statements on PostgreSQL 9.5+ (jeremyevans) (#1656)
26
+
27
+ * Implement Sequel::Postgres::PGRange#hash so instances work correctly in hashes (jeremyevans) (#1648)
28
+
29
+ * Make dirty plugin work correctly with typecast_on_load plugin (jeremyevans) (#1647)
30
+
31
+ * Add support for :require_modification option when setting up nested_attributes (jeremyevans)
32
+
33
+ * Add support for SQL/JSON path expressions to the pg_json_ops extension, supported by PostgreSQL 12+ (jeremyevans)
34
+
35
+ === 5.25.0 (2019-10-01)
36
+
37
+ * Fix Sequel::SQL::NumericMethods#coerce to not raise NoMethodError if super method is not defined (jeremyevans) (#1645)
38
+
39
+ * Allow setting a default for a column that already has a default on Microsoft SQL Server (jeremyevans)
40
+
41
+ * Fix keyword argument separation warnings on Ruby master branch in csv_serializer plugin (jeremyevans)
42
+
43
+ * Add association_multi_add_remove plugin for adding/removing multiple associated objects in a single method call (AlexWayfer, jeremyevans) (#1641, #1643)
44
+
45
+ * Make sharding plugin integrate with server_block extension (jeremyevans)
46
+
47
+ === 5.24.0 (2019-09-01)
48
+
49
+ * Add Database#skip_logging? private method designed for extensions to force query timing even if no logger is present (adam12) (#1640)
50
+
51
+ * Allow a hostname specified in a defaults_file in the mysql2 adapter, by not explicitly setting :host (sapio-bdeamer) (#1638)
52
+
53
+ * Convert all database array types to Ruby arrays in the jdbc adapter (jeremyevans)
54
+
55
+ * Add static_cache_cache plugin for caching rows for static_cache models to a file to avoid database queries during model initialization (jeremyevans)
56
+
57
+ * Add :cache_file plugin option to pg_auto_constraint_validations plugin, for caching metadata to a file for faster initialization (jeremyevans)
58
+
59
+ * Support :unique_deferrable and :primary_key_deferrable column options (jeremyevans)
60
+
61
+ * Support :generated_always_as column option on PostgreSQL 12+ (jeremyevans)
62
+
1
63
  === 5.23.0 (2019-08-01)
2
64
 
3
65
  * Work around a bug on jdbc-sqlite3 3.27.2.1 when parsing schema for tables with columns with default values (jeremyevans)
@@ -578,7 +578,7 @@ A single model instance can also be fetched by specifying a condition:
578
578
  post = Post.first(title: 'hello world')
579
579
  post = Post.first{num_comments < 10}
580
580
 
581
- The dataset for a model class returns rows a model instances instead of plain hashes:
581
+ The dataset for a model class returns rows of model instances instead of plain hashes:
582
582
 
583
583
  DB[:posts].first.class # => Hash
584
584
  Post.first.class # => Post
@@ -55,6 +55,7 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
55
55
 
56
56
  dataset.exclude(:active).delete
57
57
  dataset.where{price < 100}.update(:active => true)
58
+ dataset.where(:active).update(:price => Sequel[:price] * 0.90)
58
59
 
59
60
  == Datasets are Enumerable
60
61
 
@@ -341,12 +341,12 @@ Dataset#overriding_system_value and Dataset#overriding_user_value to use this ne
341
341
  syntax:
342
342
 
343
343
  DB.create_table(:table){primary_key :id}
344
- # Ignore the given value for id, using the identity's sequence value
344
+ # Ignore the given value for id, using the identity's sequence value.
345
345
  DB[:table].overriding_user_value.insert(:id=>1)
346
346
 
347
347
  DB.create_table(:table){primary_key :id, :identity=>:always}
348
348
  # Force the use of the given value for id, because otherwise the insert will
349
- # raise an error, since GENERATED ALWAYS was using when creating the column.
349
+ # raise an error, since GENERATED ALWAYS was used when creating the column.
350
350
  DB[:table].overriding_system_value.insert(:id=>1)
351
351
 
352
352
  === Distinct On Specific Columns
@@ -0,0 +1,56 @@
1
+ = New Features
2
+
3
+ * A :cache_file plugin option has been added to the
4
+ pg_auto_constraint_validations plugin. This option specifies
5
+ a file to use to cache the metadata the plugin uses, so the
6
+ plugin does not need to run 5 queries per model at startup to
7
+ load the metadata. This can dramatically improve startup time
8
+ when using the plugin with a large number of models.
9
+
10
+ To create the metadata file, load the plugin into Sequel::Model
11
+ (or whatever class you are using as the base class for your
12
+ model classes) with the :cache_file option, and after loading
13
+ all of the subclasses of that class, run:
14
+
15
+ Sequel::Model.dump_pg_auto_constraint_validations_cache
16
+
17
+ As when using the schema_caching and index_caching extensions,
18
+ it is up to the user to ensure that the cached metadata matches
19
+ the current database schema. Sequel does no checking of this,
20
+ as checking would take more time, and the point of this plugin
21
+ is to improve startup performance.
22
+
23
+ * A static_cache_cache plugin has been added. This plugin allows
24
+ for caching rows for models using the static_cache plugin. This
25
+ prevents the need to issue a query at model creation time to
26
+ get the rows. This plugin should be loaded into Sequel::Model
27
+ (or whatever class you are using as the base class for your
28
+ model classes) before loading the models using the static_cache
29
+ plugin. To create the metadata file, after all subclasses of
30
+ that class have been loaded, run:
31
+
32
+ Sequel::Model.dump_static_cache_cache
33
+
34
+ * :unique_deferrable and :primary_key_deferrable column
35
+ options are now supported on PostgreSQL 9+ and Oracle. This
36
+ allows you to created deferrable unique and primary key
37
+ column constraints. You could already create deferrable
38
+ table constraints using the :deferrable option to the primary_key
39
+ and unique methods.
40
+
41
+ * A :generated_always_as column option is now supported on
42
+ PostgreSQL 12+, for creating generated columns.
43
+
44
+ * A Database#skip_logging? private method has been added. This
45
+ is designed for use in extensions, to force log timing even
46
+ when no loggers are configured.
47
+
48
+ = Other Improvements
49
+
50
+ * Sequel no longer sets the :host option to localhost by default
51
+ in the mysql2 adapter. This prevents Sequel from overriding
52
+ a host specified in the defaults_file.
53
+
54
+ * All database array types are converted to Ruby arrays in the
55
+ jdbc adapter. Previously, this was only done in the
56
+ jdbc/postgresql subadapter.
@@ -0,0 +1,32 @@
1
+ = New Features
2
+
3
+ * An association_multi_add_remove plugin has been added. This plugin
4
+ adds a shortcut for adding or removing multiple associated objects
5
+ in a single method call:
6
+
7
+ Artist.plugin :association_multi_add_remove
8
+ Artist.many_to_one :albums
9
+ Artist[1].add_albums([Album[2], Album[3]])
10
+ Artist[1].remove_albums([Album[4], Album[5]])
11
+
12
+ It also offers a setter method, which will add and remove associated
13
+ objects as necessary:
14
+
15
+ Artist[1].albums = [Album[3], Album[4]]
16
+
17
+ = Other Improvements
18
+
19
+ * The sharding plugin now integrates with the server_block extension.
20
+ This makes it so if you retrieve a model instance inside a
21
+ with_server block, saving the model instance will save it back to
22
+ the shard from which it was retrieved.
23
+
24
+ * Setting a default for a column on Microsoft SQL Server now works
25
+ correctly if the column already has a default.
26
+
27
+ * Sequel::SQL::NumericMethods#coerce no longer raises NoMethodError
28
+ if the super method is not defined. This fixes some cases when
29
+ comparing Date/DateTime instances to Sequel objects.
30
+
31
+ * The csv_serializer plugin now avoids keyword argument separation
32
+ issues on Ruby 2.7+.
@@ -0,0 +1,35 @@
1
+ = New Features
2
+
3
+ * Support for SQL/JSON path expressions has been added to the
4
+ pg_json_ops extension. These are supported in PostgreSQL 12+.
5
+ Examples:
6
+
7
+ j = Sequel.pg_json_op(:json_column)
8
+ j.path_exists('$.foo') # (jsonb_column @? '$.foo')
9
+ j.path_match('$.foo') # (jsonb_column @@ '$.foo')
10
+ j.path_exists!('$.foo') # jsonb_path_exists(jsonb_column, '$.foo')
11
+ j.path_match!('$.foo') # jsonb_path_match(jsonb_column, '$.foo')
12
+ j.path_query('$.foo') # jsonb_path_query(jsonb_column, '$.foo')
13
+ j.path_query_array('$.foo') # jsonb_path_query_array(jsonb_column, '$.foo')
14
+ j.path_query_first('$.foo') # jsonb_path_query_first(jsonb_column, '$.foo')
15
+
16
+ * The nested_attributes method in the nested_attributes plugin now
17
+ supports a :require_modification option, which can override the
18
+ default require_modification setting for the nested objects. This
19
+ can be useful to avoid errors if multiple requests are submitted
20
+ simultaneously to delete the same nested row.
21
+
22
+ = Other Improvements
23
+
24
+ * The dirty plugin now works correctly with the typecast_on_load
25
+ plugin.
26
+
27
+ * Sequel::Postgres::PGRange#hash has been added to the pg_range
28
+ extension, allowing PGRange instances to be usable as hash keys.
29
+
30
+ * Table aliases are now supported for single table INSERT
31
+ statements on PostgreSQL 9.5+, which can make some insert_conflict
32
+ usage easier.
33
+
34
+ * Two more foreign key constraint violation types are now recognized
35
+ on MySQL 8.0.13+.
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * Sequel::DEFAULT has been added a constant for the DEFAULT expression,
4
+ useful in inserts and especially updates:
5
+
6
+ DB[:a].where(:id=>1).update(:b=>Sequel::DEFAULT)
7
+ # UPDATE "a" SET "b" = DEFAULT WHERE "id" = 1
8
+
9
+ * SQL::Function#filter for filtered aggregate functions is now
10
+ supported on all databases. On databases not supporting it natively
11
+ (all except PostgreSQL 9.4+ and SQLite 3.30+), a CASE statement is
12
+ used to emulate the support.
13
+
14
+ = Other Improvements
15
+
16
+ * NULLS FIRST/LAST is now used without emulation on SQLite 3.30+.
17
+
18
+ * The pg_enum extension now works correctly on PostgreSQL 8.3-9.0.
19
+
20
+ * Postgres::ArrayOp#join in the pg_array_ops extension now works
21
+ correctly on PostgreSQL <9.1.
@@ -0,0 +1,16 @@
1
+ = New Features
2
+
3
+ * An any_not_empty extension has been added, for making Dataset#any?
4
+ without a block be the same as !empty?. This can result in a
5
+ much faster database query.
6
+
7
+ * An exclude_or_null extension has been added, adding a
8
+ Dataset#exclude_or_null method that returns rows where the given
9
+ expression is false or NULL. This extension is supported on
10
+ PostgreSQL, SQLite, MySQL, H2, and HSQLDB.
11
+
12
+ = Other Improvements
13
+
14
+ * When using the jdbc/postgresql adapter, calling with_fetch_size
15
+ on a dataset will emit a warning. This is because the driver
16
+ will ignore the setting.
@@ -8,17 +8,20 @@ These run each test in its own transaction, the recommended way to test.
8
8
 
9
9
  === minitest/spec
10
10
 
11
- ==== with minitest-hooks
12
-
11
+ ==== with minitest-hooks
13
12
  require 'minitest/hooks/default'
13
+
14
+ DB = Sequel.postgres # change if using sqlite etc
15
+
14
16
  class Minitest::HooksSpec
15
17
  def around
16
18
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
17
19
  end
18
20
  end
19
21
 
20
- ==== without minitest-hooks
21
-
22
+ ==== without minitest-hooks
23
+ DB = Sequel.postgres # change if using sqlite etc
24
+
22
25
  class Minitest::Spec
23
26
  def run(*args, &block)
24
27
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){super}
@@ -26,7 +29,8 @@ These run each test in its own transaction, the recommended way to test.
26
29
  end
27
30
 
28
31
  === minitest/test
29
-
32
+ DB = Sequel.postgres # change if using sqlite etc
33
+
30
34
  # Use this class as the base class for your tests
31
35
  class SequelTestCase < Minitest::Test
32
36
  def run(*args, &block)
@@ -35,7 +39,8 @@ These run each test in its own transaction, the recommended way to test.
35
39
  end
36
40
 
37
41
  === rspec >= 2.8
38
-
42
+ DB = Sequel.postgres # change the database if you are using sqlite etc.
43
+
39
44
  RSpec.configure do |c|
40
45
  c.around(:each) do |example|
41
46
  DB.transaction(:rollback=>:always, :auto_savepoint=>true){example.run}
@@ -102,12 +102,17 @@ module Sequel
102
102
  v.getSubString(1, v.length)
103
103
  end
104
104
  end
105
+ x = convertors[:RubyArray] = Object.new
106
+ def x.call(r, i)
107
+ if v = r.getArray(i)
108
+ v.array.to_ary
109
+ end
110
+ end
105
111
 
106
112
  MAP = Hash.new(convertors[:Object])
107
113
  types = Java::JavaSQL::Types
108
114
 
109
115
  {
110
- :ARRAY => :Array,
111
116
  :BOOLEAN => :Boolean,
112
117
  :CHAR => :String,
113
118
  :DOUBLE => :Double,
@@ -126,6 +131,7 @@ module Sequel
126
131
  BASIC_MAP = MAP.dup
127
132
 
128
133
  {
134
+ :ARRAY => :Array,
129
135
  :BINARY => :Blob,
130
136
  :BLOB => :Blob,
131
137
  :CLOB => :Clob,
@@ -180,6 +180,12 @@ module Sequel
180
180
 
181
181
  class Dataset < JDBC::Dataset
182
182
  include Sequel::Postgres::DatasetMethods
183
+
184
+ # Warn when calling as the fetch size is ignored by the JDBC adapter currently.
185
+ def with_fetch_size(size)
186
+ warn("Sequel::JDBC::Postgres::Dataset#with_fetch_size does not currently have an effect.", :uplevel=>1)
187
+ super
188
+ end
183
189
 
184
190
  private
185
191
 
@@ -195,17 +201,7 @@ module Sequel
195
201
 
196
202
  STRING_TYPE = Java::JavaSQL::Types::VARCHAR
197
203
  ARRAY_TYPE = Java::JavaSQL::Types::ARRAY
198
- PG_SPECIFIC_TYPES = [ARRAY_TYPE, Java::JavaSQL::Types::OTHER, Java::JavaSQL::Types::STRUCT, Java::JavaSQL::Types::TIME_WITH_TIMEZONE, Java::JavaSQL::Types::TIME].freeze
199
-
200
- # Return PostgreSQL array types as ruby Arrays instead of
201
- # JDBC PostgreSQL driver-specific array type. Only used if the
202
- # database does not have a conversion proc for the type.
203
- ARRAY_METHOD = Object.new
204
- def ARRAY_METHOD.call(r, i)
205
- if v = r.getArray(i)
206
- v.array.to_ary
207
- end
208
- end
204
+ PG_SPECIFIC_TYPES = [Java::JavaSQL::Types::ARRAY, Java::JavaSQL::Types::OTHER, Java::JavaSQL::Types::STRUCT, Java::JavaSQL::Types::TIME_WITH_TIMEZONE, Java::JavaSQL::Types::TIME].freeze
209
205
 
210
206
  # Return PostgreSQL hstore types as ruby Hashes instead of
211
207
  # Java HashMaps. Only used if the database does not have a
@@ -223,8 +219,6 @@ module Sequel
223
219
  oid = meta.getField(i).getOID
224
220
  if pr = db.oid_convertor_proc(oid)
225
221
  pr
226
- elsif type == ARRAY_TYPE
227
- ARRAY_METHOD
228
222
  elsif oid == 2950 # UUID
229
223
  map[STRING_TYPE]
230
224
  elsif meta.getPGType(i) == 'hstore'
@@ -36,7 +36,6 @@ module Sequel
36
36
  # options such as :local_infile.
37
37
  def connect(server)
38
38
  opts = server_opts(server)
39
- opts[:host] ||= 'localhost'
40
39
  opts[:username] ||= opts.delete(:user)
41
40
  opts[:flags] ||= 0
42
41
  opts[:flags] |= ::Mysql2::Client::FOUND_ROWS if ::Mysql2::Client.const_defined?(:FOUND_ROWS)
@@ -279,7 +279,7 @@ module Sequel
279
279
  end
280
280
  end
281
281
  sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
282
- sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default)) if default
282
+ sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default, :skip_drop_default=>true)) if default
283
283
  sqls
284
284
  when :set_column_null
285
285
  sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
@@ -290,7 +290,9 @@ module Sequel
290
290
  end
291
291
  "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
292
292
  when :set_column_default
293
- "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
293
+ sqls = []
294
+ add_drop_default_constraint_sql(sqls, table, op[:name]) unless op[:skip_drop_default]
295
+ sqls << "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
294
296
  else
295
297
  super(table, op)
296
298
  end
@@ -97,13 +97,17 @@ module Sequel
97
97
  # Add an exclusion constraint when creating the table. Elements should be
98
98
  # an array of 2 element arrays, with the first element being the column or
99
99
  # expression the exclusion constraint is applied to, and the second element
100
- # being the operator to use for the column/expression to check for exclusion.
101
- #
102
- # Example:
100
+ # being the operator to use for the column/expression to check for exclusion:
103
101
  #
104
102
  # exclude([[:col1, '&&'], [:col2, '=']])
105
103
  # # EXCLUDE USING gist (col1 WITH &&, col2 WITH =)
106
104
  #
105
+ # To use a custom operator class, you need to use Sequel.lit with the expression
106
+ # and operator class:
107
+ #
108
+ # exclude([[Sequel.lit('col1 inet_ops'), '&&'], [:col2, '=']])
109
+ # # EXCLUDE USING gist (col1 inet_ops WITH &&, col2 WITH =)
110
+ #
107
111
  # Options supported:
108
112
  #
109
113
  # :name :: Name the constraint with the given name (useful if you may
@@ -836,10 +840,14 @@ module Sequel
836
840
  # default value is given.
837
841
  def column_definition_default_sql(sql, column)
838
842
  super
839
- if !column[:serial] && !['serial', 'bigserial'].include?(column[:type].to_s) && !column[:default] && (identity = column[:identity])
840
- sql << " GENERATED "
841
- sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
842
- sql << " AS IDENTITY"
843
+ if !column[:serial] && !['serial', 'bigserial'].include?(column[:type].to_s) && !column[:default]
844
+ if (identity = column[:identity])
845
+ sql << " GENERATED "
846
+ sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
847
+ sql << " AS IDENTITY"
848
+ elsif (generated = column[:generated_always_as])
849
+ sql << " GENERATED ALWAYS AS (#{literal(generated)}) STORED"
850
+ end
843
851
  end
844
852
  end
845
853
 
@@ -1798,6 +1806,16 @@ module Sequel
1798
1806
  end
1799
1807
  end
1800
1808
 
1809
+ # Include aliases when inserting into a single table on PostgreSQL 9.5+.
1810
+ def insert_into_sql(sql)
1811
+ sql << " INTO "
1812
+ if (f = @opts[:from]) && f.length == 1
1813
+ identifier_append(sql, server_version >= 90500 ? f.first : unaliased_identifier(f.first))
1814
+ else
1815
+ source_list_append(sql, f)
1816
+ end
1817
+ end
1818
+
1801
1819
  # Return the primary key to use for RETURNING in an INSERT statement
1802
1820
  def insert_pk
1803
1821
  if (f = opts[:from]) && !f.empty?
@@ -1937,6 +1955,11 @@ module Sequel
1937
1955
  db.server_version(@opts[:server])
1938
1956
  end
1939
1957
 
1958
+ # PostgreSQL 9.4+ supports the FILTER clause for aggregate functions.
1959
+ def supports_filtered_aggregates?
1960
+ server_version >= 90400
1961
+ end
1962
+
1940
1963
  # PostgreSQL supports quoted function names.
1941
1964
  def supports_quoted_function_names?
1942
1965
  true