sequel 4.45.0 → 4.46.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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +108 -0
  3. data/doc/release_notes/4.46.0.txt +404 -0
  4. data/doc/security.rdoc +9 -0
  5. data/doc/sql.rdoc +2 -2
  6. data/doc/testing.rdoc +1 -1
  7. data/doc/validations.rdoc +1 -2
  8. data/lib/sequel/adapters/ado.rb +8 -3
  9. data/lib/sequel/adapters/ado/access.rb +8 -4
  10. data/lib/sequel/adapters/ado/mssql.rb +3 -1
  11. data/lib/sequel/adapters/amalgalite.rb +5 -0
  12. data/lib/sequel/adapters/cubrid.rb +16 -7
  13. data/lib/sequel/adapters/do.rb +7 -1
  14. data/lib/sequel/adapters/do/mysql.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +10 -5
  16. data/lib/sequel/adapters/jdbc.rb +8 -2
  17. data/lib/sequel/adapters/jdbc/as400.rb +10 -3
  18. data/lib/sequel/adapters/jdbc/db2.rb +27 -16
  19. data/lib/sequel/adapters/jdbc/derby.rb +47 -20
  20. data/lib/sequel/adapters/jdbc/h2.rb +13 -7
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
  22. data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
  24. data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
  26. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
  29. data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
  30. data/lib/sequel/adapters/mock.rb +5 -0
  31. data/lib/sequel/adapters/mysql.rb +8 -1
  32. data/lib/sequel/adapters/mysql2.rb +6 -1
  33. data/lib/sequel/adapters/odbc.rb +20 -8
  34. data/lib/sequel/adapters/odbc/mssql.rb +6 -3
  35. data/lib/sequel/adapters/oracle.rb +12 -6
  36. data/lib/sequel/adapters/postgres.rb +20 -8
  37. data/lib/sequel/adapters/shared/access.rb +76 -47
  38. data/lib/sequel/adapters/shared/cubrid.rb +16 -11
  39. data/lib/sequel/adapters/shared/db2.rb +46 -19
  40. data/lib/sequel/adapters/shared/firebird.rb +20 -8
  41. data/lib/sequel/adapters/shared/informix.rb +6 -3
  42. data/lib/sequel/adapters/shared/mssql.rb +132 -72
  43. data/lib/sequel/adapters/shared/mysql.rb +112 -65
  44. data/lib/sequel/adapters/shared/oracle.rb +36 -21
  45. data/lib/sequel/adapters/shared/postgres.rb +91 -56
  46. data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
  47. data/lib/sequel/adapters/shared/sqlite.rb +67 -32
  48. data/lib/sequel/adapters/sqlanywhere.rb +9 -1
  49. data/lib/sequel/adapters/sqlite.rb +8 -1
  50. data/lib/sequel/adapters/swift.rb +5 -0
  51. data/lib/sequel/adapters/swift/mysql.rb +4 -2
  52. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  53. data/lib/sequel/adapters/tinytds.rb +10 -3
  54. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  55. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  56. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  57. data/lib/sequel/adapters/utils/pg_types.rb +14 -6
  58. data/lib/sequel/adapters/utils/replace.rb +4 -2
  59. data/lib/sequel/connection_pool/single.rb +2 -2
  60. data/lib/sequel/core.rb +24 -11
  61. data/lib/sequel/database/connecting.rb +9 -3
  62. data/lib/sequel/database/dataset_defaults.rb +7 -1
  63. data/lib/sequel/database/logging.rb +1 -0
  64. data/lib/sequel/database/misc.rb +5 -2
  65. data/lib/sequel/database/query.rb +7 -5
  66. data/lib/sequel/database/schema_generator.rb +1 -0
  67. data/lib/sequel/database/schema_methods.rb +50 -27
  68. data/lib/sequel/database/transactions.rb +19 -9
  69. data/lib/sequel/dataset/actions.rb +15 -6
  70. data/lib/sequel/dataset/graph.rb +15 -5
  71. data/lib/sequel/dataset/misc.rb +12 -4
  72. data/lib/sequel/dataset/mutation.rb +17 -8
  73. data/lib/sequel/dataset/prepared_statements.rb +3 -2
  74. data/lib/sequel/dataset/query.rb +84 -38
  75. data/lib/sequel/dataset/sql.rb +302 -191
  76. data/lib/sequel/deprecated.rb +26 -17
  77. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
  78. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  79. data/lib/sequel/extensions/from_block.rb +1 -0
  80. data/lib/sequel/extensions/graph_each.rb +1 -1
  81. data/lib/sequel/extensions/identifier_mangling.rb +2 -2
  82. data/lib/sequel/extensions/migration.rb +28 -4
  83. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
  84. data/lib/sequel/extensions/schema_dumper.rb +4 -4
  85. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
  86. data/lib/sequel/extensions/set_overrides.rb +2 -0
  87. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  88. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  89. data/lib/sequel/model.rb +11 -7
  90. data/lib/sequel/model/associations.rb +5 -7
  91. data/lib/sequel/model/base.rb +47 -45
  92. data/lib/sequel/model/dataset_module.rb +9 -14
  93. data/lib/sequel/model/plugins.rb +3 -0
  94. data/lib/sequel/no_core_ext.rb +1 -0
  95. data/lib/sequel/plugins/blacklist_security.rb +1 -1
  96. data/lib/sequel/plugins/boolean_subsets.rb +7 -5
  97. data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
  98. data/lib/sequel/plugins/dataset_associations.rb +1 -1
  99. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  100. data/lib/sequel/plugins/finder.rb +240 -0
  101. data/lib/sequel/plugins/inverted_subsets.rb +19 -12
  102. data/lib/sequel/plugins/many_through_many.rb +1 -1
  103. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  104. data/lib/sequel/plugins/schema.rb +1 -1
  105. data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
  106. data/lib/sequel/plugins/subset_conditions.rb +11 -3
  107. data/lib/sequel/plugins/whitelist_security.rb +118 -0
  108. data/lib/sequel/sql.rb +80 -36
  109. data/lib/sequel/timezones.rb +2 -0
  110. data/lib/sequel/version.rb +1 -1
  111. data/spec/adapters/mssql_spec.rb +20 -0
  112. data/spec/adapters/mysql_spec.rb +1 -1
  113. data/spec/adapters/oracle_spec.rb +12 -8
  114. data/spec/adapters/postgres_spec.rb +1 -1
  115. data/spec/adapters/spec_helper.rb +1 -1
  116. data/spec/adapters/sqlite_spec.rb +36 -34
  117. data/spec/core/connection_pool_spec.rb +2 -1
  118. data/spec/core/database_spec.rb +87 -9
  119. data/spec/core/dataset_spec.rb +501 -129
  120. data/spec/core/deprecated_spec.rb +1 -1
  121. data/spec/core/expression_filters_spec.rb +146 -60
  122. data/spec/core/mock_adapter_spec.rb +1 -1
  123. data/spec/core/object_graph_spec.rb +61 -9
  124. data/spec/core/placeholder_literalizer_spec.rb +20 -2
  125. data/spec/core/schema_generator_spec.rb +6 -6
  126. data/spec/core/schema_spec.rb +54 -5
  127. data/spec/core_extensions_spec.rb +122 -18
  128. data/spec/deprecation_helper.rb +27 -2
  129. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
  130. data/spec/extensions/association_proxies_spec.rb +2 -2
  131. data/spec/extensions/auto_literal_strings_spec.rb +212 -0
  132. data/spec/extensions/blacklist_security_spec.rb +1 -0
  133. data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
  134. data/spec/extensions/column_select_spec.rb +20 -8
  135. data/spec/extensions/columns_introspection_spec.rb +3 -3
  136. data/spec/extensions/core_refinements_spec.rb +29 -12
  137. data/spec/extensions/dataset_associations_spec.rb +12 -12
  138. data/spec/extensions/def_dataset_method_spec.rb +100 -0
  139. data/spec/extensions/error_sql_spec.rb +1 -1
  140. data/spec/extensions/finder_spec.rb +260 -0
  141. data/spec/extensions/graph_each_spec.rb +2 -2
  142. data/spec/extensions/identifier_mangling_spec.rb +14 -8
  143. data/spec/extensions/inverted_subsets_spec.rb +4 -4
  144. data/spec/extensions/lazy_attributes_spec.rb +7 -0
  145. data/spec/extensions/many_through_many_spec.rb +38 -14
  146. data/spec/extensions/nested_attributes_spec.rb +18 -6
  147. data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
  148. data/spec/extensions/pg_enum_spec.rb +16 -1
  149. data/spec/extensions/pg_interval_spec.rb +11 -2
  150. data/spec/extensions/pg_loose_count_spec.rb +5 -0
  151. data/spec/extensions/pg_row_spec.rb +25 -0
  152. data/spec/extensions/prepared_statements_spec.rb +10 -1
  153. data/spec/extensions/query_spec.rb +2 -2
  154. data/spec/extensions/schema_dumper_spec.rb +2 -2
  155. data/spec/extensions/schema_spec.rb +2 -2
  156. data/spec/extensions/set_overrides_spec.rb +7 -3
  157. data/spec/extensions/sql_expr_spec.rb +0 -1
  158. data/spec/extensions/subset_conditions_spec.rb +6 -6
  159. data/spec/extensions/table_select_spec.rb +24 -12
  160. data/spec/extensions/to_dot_spec.rb +4 -4
  161. data/spec/extensions/whitelist_security_spec.rb +131 -0
  162. data/spec/integration/dataset_test.rb +9 -5
  163. data/spec/integration/model_test.rb +2 -0
  164. data/spec/integration/plugin_test.rb +2 -2
  165. data/spec/integration/spec_helper.rb +1 -1
  166. data/spec/model/associations_spec.rb +39 -11
  167. data/spec/model/base_spec.rb +44 -24
  168. data/spec/model/class_dataset_methods_spec.rb +18 -16
  169. data/spec/model/dataset_methods_spec.rb +4 -4
  170. data/spec/model/eager_loading_spec.rb +84 -24
  171. data/spec/model/model_spec.rb +97 -63
  172. data/spec/model/record_spec.rb +21 -13
  173. metadata +13 -2
@@ -10,20 +10,29 @@ module Sequel
10
10
  # ---------------------
11
11
 
12
12
  SQL_BEGIN = 'BEGIN'.freeze
13
+ Sequel::Deprecation.deprecate_constant(self, :SQL_BEGIN)
13
14
  SQL_COMMIT = 'COMMIT'.freeze
15
+ Sequel::Deprecation.deprecate_constant(self, :SQL_COMMIT)
14
16
  SQL_RELEASE_SAVEPOINT = 'RELEASE SAVEPOINT autopoint_%d'.freeze
17
+ Sequel::Deprecation.deprecate_constant(self, :SQL_RELEASE_SAVEPOINT)
15
18
  SQL_ROLLBACK = 'ROLLBACK'.freeze
19
+ Sequel::Deprecation.deprecate_constant(self, :SQL_ROLLBACK)
16
20
  SQL_ROLLBACK_TO_SAVEPOINT = 'ROLLBACK TO SAVEPOINT autopoint_%d'.freeze
21
+ Sequel::Deprecation.deprecate_constant(self, :SQL_ROLLBACK_TO_SAVEPOINT)
17
22
  SQL_SAVEPOINT = 'SAVEPOINT autopoint_%d'.freeze
23
+ Sequel::Deprecation.deprecate_constant(self, :SQL_SAVEPOINT)
18
24
 
19
25
  TRANSACTION_BEGIN = 'Transaction.begin'.freeze
26
+ Sequel::Deprecation.deprecate_constant(self, :TRANSACTION_BEGIN)
20
27
  TRANSACTION_COMMIT = 'Transaction.commit'.freeze
28
+ Sequel::Deprecation.deprecate_constant(self, :TRANSACTION_COMMIT)
21
29
  TRANSACTION_ROLLBACK = 'Transaction.rollback'.freeze
30
+ Sequel::Deprecation.deprecate_constant(self, :TRANSACTION_ROLLBACK)
22
31
 
23
32
  TRANSACTION_ISOLATION_LEVELS = {:uncommitted=>'READ UNCOMMITTED'.freeze,
24
33
  :committed=>'READ COMMITTED'.freeze,
25
34
  :repeatable=>'REPEATABLE READ'.freeze,
26
- :serializable=>'SERIALIZABLE'.freeze}
35
+ :serializable=>'SERIALIZABLE'.freeze}#.freeze # SEQUEL5
27
36
 
28
37
  # The default transaction isolation level for this database,
29
38
  # used for all future transactions. For MSSQL, this should be set
@@ -122,7 +131,7 @@ module Sequel
122
131
  # use a savepoint you must use this option. If the surrounding transaction
123
132
  # uses :auto_savepoint, you can set this to false to not use a savepoint.
124
133
  # If the value given for this option is :only, it will only create a
125
- # savepoint if it is inside a transacation.
134
+ # savepoint if it is inside a transaction.
126
135
  #
127
136
  # PostgreSQL specific options:
128
137
  #
@@ -217,9 +226,10 @@ module Sequel
217
226
  rescue Exception => e
218
227
  begin
219
228
  rollback_transaction(conn, opts)
220
- rescue Exception
229
+ rescue Exception => e3
221
230
  end
222
231
  transaction_error(e, :conn=>conn, :rollback=>rollback)
232
+ raise e3 if e3
223
233
  ret
224
234
  ensure
225
235
  begin
@@ -292,7 +302,7 @@ module Sequel
292
302
 
293
303
  # SQL to start a new savepoint
294
304
  def begin_savepoint_sql(depth)
295
- SQL_SAVEPOINT % depth
305
+ "SAVEPOINT autopoint_#{depth}"
296
306
  end
297
307
 
298
308
  # Start a new database connection on the given connection
@@ -316,7 +326,7 @@ module Sequel
316
326
 
317
327
  # SQL to BEGIN a transaction.
318
328
  def begin_transaction_sql
319
- SQL_BEGIN
329
+ 'BEGIN'
320
330
  end
321
331
 
322
332
  # Whether to commit the current transaction. Thread.current.status is
@@ -340,7 +350,7 @@ module Sequel
340
350
 
341
351
  # SQL to commit a savepoint
342
352
  def commit_savepoint_sql(depth)
343
- SQL_RELEASE_SAVEPOINT % depth
353
+ "RELEASE SAVEPOINT autopoint_#{depth}"
344
354
  end
345
355
 
346
356
  # Commit the active transaction on the connection
@@ -355,7 +365,7 @@ module Sequel
355
365
 
356
366
  # SQL to COMMIT a transaction.
357
367
  def commit_transaction_sql
358
- SQL_COMMIT
368
+ 'COMMIT'
359
369
  end
360
370
 
361
371
  # Method called on the connection object to execute SQL on the database,
@@ -393,7 +403,7 @@ module Sequel
393
403
 
394
404
  # SQL to rollback to a savepoint
395
405
  def rollback_savepoint_sql(depth)
396
- SQL_ROLLBACK_TO_SAVEPOINT % depth
406
+ "ROLLBACK TO SAVEPOINT autopoint_#{depth}"
397
407
  end
398
408
 
399
409
  # Rollback the active transaction on the connection
@@ -408,7 +418,7 @@ module Sequel
408
418
 
409
419
  # SQL to ROLLBACK a transaction.
410
420
  def rollback_transaction_sql
411
- SQL_ROLLBACK
421
+ 'ROLLBACK'
412
422
  end
413
423
 
414
424
  # Set the transaction isolation level on the given connection
@@ -34,7 +34,7 @@ module Sequel
34
34
  # DB[:table][:id=>1] # SELECT * FROM table WHERE (id = 1) LIMIT 1
35
35
  # # => {:id=1}
36
36
  def [](*conditions)
37
- raise(Error, ARRAY_ACCESS_ERROR_MSG) if (conditions.length == 1 and conditions.first.is_a?(Integer)) or conditions.length == 0
37
+ raise(Error, 'You cannot call Dataset#[] with an integer or with no arguments') if (conditions.length == 1 and conditions.first.is_a?(Integer)) or conditions.length == 0
38
38
  first(*conditions)
39
39
  end
40
40
 
@@ -104,7 +104,8 @@ module Sequel
104
104
  def count(arg=(no_arg=true), &block)
105
105
  if no_arg && !block
106
106
  cached_dataset(:_count_ds) do
107
- aggregate_dataset.select{count{}.*.as(:count)}.single_value_ds
107
+ aggregate_dataset.select(Sequel.function(:count).*.as(:count)).single_value_ds
108
+ #aggregate_dataset.select(COUNT_SELECT).single_value_ds # SEQUEL5
108
109
  end.single_value!.to_i
109
110
  else
110
111
  if block
@@ -118,6 +119,9 @@ module Sequel
118
119
  _aggregate(:count, arg)
119
120
  end
120
121
  end
122
+ # SEQUEL5
123
+ #COUNT_SELECT = Sequel.function(:count).*.as(:count)
124
+ #private_constant :COUNT_SELECT
121
125
 
122
126
  # Deletes the records in the dataset. The returned value should be
123
127
  # number of records deleted, but that is adapter dependent.
@@ -158,8 +162,12 @@ module Sequel
158
162
  def empty?
159
163
  cached_dataset(:_empty_ds) do
160
164
  single_value_ds.unordered.select(Sequel::SQL::AliasedExpression.new(1, :one))
165
+ # single_value_ds.unordered.select(EMPTY_SELECT) # SEQUEL5
161
166
  end.single_value!.nil?
162
167
  end
168
+ # SEQUEL5
169
+ #EMPTY_SELECT = Sequel::SQL::AliasedExpression.new(1, :one)
170
+ #private_constant :EMPTY_SELECT
163
171
 
164
172
  # If a integer argument is given, it is interpreted as a limit, and then returns all
165
173
  # matching records up to that limit. If no argument is passed,
@@ -267,7 +275,7 @@ module Sequel
267
275
  def get(column=(no_arg=true; nil), &block)
268
276
  ds = naked
269
277
  if block
270
- raise(Error, ARG_BLOCK_ERROR_MSG) unless no_arg
278
+ raise(Error, 'Must call Dataset#get with an argument or a block, not both') unless no_arg
271
279
  ds = ds.select(&block)
272
280
  column = ds.opts[:select]
273
281
  column = nil if column.is_a?(Array) && column.length < 2
@@ -334,7 +342,7 @@ module Sequel
334
342
  return @db.transaction{insert(columns, values)} if values.is_a?(Dataset)
335
343
 
336
344
  return if values.empty?
337
- raise(Error, IMPORT_ERROR_MSG) if columns.empty?
345
+ raise(Error, 'Using Sequel::Dataset#import with an empty column array is not allowed') if columns.empty?
338
346
  ds = opts[:server] ? server(opts[:server]) : self
339
347
 
340
348
  if slice_size = opts.fetch(:commit_every, opts.fetch(:slice, default_import_slice))
@@ -444,7 +452,7 @@ module Sequel
444
452
  # # => [[1, 'A'], [2, 'B'], [3, 'C'], ...]
445
453
  def map(column=nil, &block)
446
454
  if column
447
- raise(Error, ARG_BLOCK_ERROR_MSG) if block
455
+ raise(Error, 'Must call Dataset#map with either an argument or a block, not both') if block
448
456
  return naked.map(column) if row_proc
449
457
  if column.is_a?(Array)
450
458
  super(){|r| r.values_at(*column)}
@@ -972,7 +980,8 @@ module Sequel
972
980
 
973
981
  # Returns an array of the first value in each row.
974
982
  def _select_map_single
975
- map{|r| r.values.first}
983
+ k = nil
984
+ map{|r| r[k||=r.keys.first]}
976
985
  end
977
986
 
978
987
  # A dataset for returning single values from the current dataset.
@@ -16,11 +16,16 @@ module Sequel
16
16
  # DB[:table].add_graph_aliases(:some_alias=>[:table, :column])
17
17
  # # SELECT ..., table.column AS some_alias
18
18
  def add_graph_aliases(graph_aliases)
19
- unless (ga = opts[:graph_aliases]) || (opts[:graph] && (ga = opts[:graph][:column_aliases]))
19
+ graph = opts[:graph]
20
+ unless (ga = opts[:graph_aliases]) || (graph && (ga = graph[:column_aliases])) # SEQUEL5: Remove graph_aliases support
20
21
  raise Error, "cannot call add_graph_aliases on a dataset that has not been called with graph or set_graph_aliases"
21
22
  end
22
23
  columns, graph_aliases = graph_alias_columns(graph_aliases)
23
- select_append(*columns).clone(:graph_aliases => Hash[ga].merge!(graph_aliases).freeze)
24
+ if opts[:graph_aliases]
25
+ select_append(*columns).clone(:graph_aliases => Hash[ga].merge!(graph_aliases).freeze) # SEQUEL5: Remove
26
+ else
27
+ select_append(*columns).clone(:graph => Hash[graph].merge!(:column_aliases=>Hash[ga].merge!(graph_aliases).freeze).freeze)
28
+ end
24
29
  end
25
30
 
26
31
  # Similar to Dataset#join_table, but uses unambiguous aliases for selected
@@ -114,7 +119,7 @@ module Sequel
114
119
  # Whether to include the table in the result set
115
120
  add_table = options[:select] == false ? false : true
116
121
  # Whether to add the columns to the list of column aliases
117
- add_columns = !ds.opts.include?(:graph_aliases)
122
+ add_columns = !ds.opts.include?(:graph_aliases) # SEQUEL5: Remove graph_aliases support
118
123
 
119
124
  if graph = opts[:graph]
120
125
  graph = graph.dup
@@ -230,13 +235,18 @@ module Sequel
230
235
  # # SELECT artists.name, albums.name AS album_name, 42 AS forty_two ...
231
236
  def set_graph_aliases(graph_aliases)
232
237
  columns, graph_aliases = graph_alias_columns(graph_aliases)
233
- select(*columns).clone(:graph_aliases=>graph_aliases.freeze)
238
+ if graph = opts[:graph]
239
+ select(*columns).clone(:graph => Hash[graph].merge!(:column_aliases=>graph_aliases.freeze).freeze)
240
+ else
241
+ Sequel::Deprecation.deprecate("Calling Dataset#set_graph_aliases before Dataset#graph", "Call Dataset#set_graph_aliases after Dataset#graph now")
242
+ select(*columns).clone(:graph_aliases=>graph_aliases.freeze) # SEQUEL5: Remove
243
+ end
234
244
  end
235
245
 
236
246
  # Remove the splitting of results into subhashes, and all metadata
237
247
  # related to the current graph (if any).
238
248
  def ungraphed
239
- clone(:graph=>nil, :graph_aliases=>nil)
249
+ clone(:graph=>nil, :graph_aliases=>nil) # SEQUEL5: Remove :graph_aliases
240
250
  end
241
251
 
242
252
  private
@@ -8,9 +8,13 @@ module Sequel
8
8
  # ---------------------
9
9
 
10
10
  NOTIMPL_MSG = "This method must be overridden in Sequel adapters".freeze
11
+ Sequel::Deprecation.deprecate_constant(self, :NOTIMPL_MSG)
11
12
  ARRAY_ACCESS_ERROR_MSG = 'You cannot call Dataset#[] with an integer or with no arguments.'.freeze
13
+ Sequel::Deprecation.deprecate_constant(self, :ARRAY_ACCESS_ERROR_MSG)
12
14
  ARG_BLOCK_ERROR_MSG = 'Must use either an argument or a block, not both'.freeze
15
+ Sequel::Deprecation.deprecate_constant(self, :ARG_BLOCK_ERROR_MSG)
13
16
  IMPORT_ERROR_MSG = 'Using Sequel::Dataset#import an empty column array is not allowed'.freeze
17
+ Sequel::Deprecation.deprecate_constant(self, :IMPORT_ERROR_MSG)
14
18
 
15
19
  # The database related to this dataset. This is the Database instance that
16
20
  # will execute all of this dataset's queries.
@@ -29,7 +33,7 @@ module Sequel
29
33
  # the Database#dataset method return an instance of that subclass.
30
34
  def initialize(db)
31
35
  @db = db
32
- @opts = {}
36
+ @opts = {} # OPTS # SEQUEL5
33
37
  @cache = {}
34
38
  end
35
39
 
@@ -50,6 +54,10 @@ module Sequel
50
54
  self == o
51
55
  end
52
56
 
57
+ # SEQUEL5: Remove other dup methods
58
+ # def dup
59
+ # self
60
+ # end
53
61
  if TRUE_FREEZE
54
62
  # Similar to #clone, but returns an unfrozen clone if the receiver is frozen.
55
63
  def dup
@@ -92,12 +100,12 @@ module Sequel
92
100
  else
93
101
  # :nocov:
94
102
  def freeze # :nodoc:
95
- @opts.freeze
103
+ @opts.freeze # SEQUEL5: remove
96
104
  self
97
105
  end
98
106
 
99
107
  def frozen? # :nodoc:
100
- @opts.frozen?
108
+ @opts.frozen? # SEQUEL5: true
101
109
  end
102
110
  # :nocov:
103
111
  end
@@ -295,7 +303,7 @@ module Sequel
295
303
  def cached_dataset(key)
296
304
  unless ds = cache_get(key)
297
305
  ds = yield
298
- cache_set(key, ds) if frozen?
306
+ cache_set(key, ds) if frozen? # SEQUEL5: Remove if frozen?
299
307
  end
300
308
 
301
309
  ds
@@ -9,6 +9,7 @@ module Sequel
9
9
 
10
10
  # All methods that should have a ! method added that modifies the receiver.
11
11
  MUTATION_METHODS = QUERY_METHODS - [:naked, :from_self]
12
+ Sequel::Deprecation.deprecate_constant(self, :MUTATION_METHODS)
12
13
 
13
14
  # Setup mutation (e.g. filter!) methods. These operate the same as the
14
15
  # non-! methods, but replace the options of the current dataset with the
@@ -26,38 +27,38 @@ module Sequel
26
27
  end
27
28
 
28
29
  # Add the mutation methods via metaprogramming
29
- def_mutation_method(*MUTATION_METHODS)
30
+ def_mutation_method(*(QUERY_METHODS - [:naked, :from_self]))
30
31
 
31
32
  # Like #extension, but modifies and returns the receiver instead of returning a modified clone.
32
33
  def extension!(*exts)
33
- raise_if_frozen!("extension!")
34
+ raise_if_frozen!(%w"extension! extension")
34
35
  _extension!(exts)
35
36
  end
36
37
 
37
38
  # Avoid self-referential dataset by cloning.
38
39
  def from_self!(*args, &block)
39
- raise_if_frozen!("from_self!")
40
+ raise_if_frozen!(%w"from_self! from_self")
40
41
  @opts = clone.from_self(*args, &block).opts
41
42
  self
42
43
  end
43
44
 
44
45
  # Remove the row_proc from the current dataset.
45
46
  def naked!
46
- raise_if_frozen!("naked=")
47
+ raise_if_frozen!(%w"naked! naked")
47
48
  @opts[:row_proc] = nil
48
49
  self
49
50
  end
50
51
 
51
52
  # Set whether to quote identifiers for this dataset
52
53
  def quote_identifiers=(v)
53
- raise_if_frozen!("quote_identifiers=")
54
+ raise_if_frozen!(%w"quote_identifiers= with_quote_identifiers")
54
55
  skip_symbol_cache!
55
56
  @opts[:quote_identifiers] = v
56
57
  end
57
58
 
58
59
  # Override the row_proc for this dataset
59
60
  def row_proc=(v)
60
- raise_if_frozen!("row_proc=")
61
+ raise_if_frozen!(%w"row_proc= with_row_proc")
61
62
  @opts[:row_proc] = v
62
63
  end
63
64
 
@@ -67,7 +68,7 @@ module Sequel
67
68
  # to the receiver and merging the options of the resulting dataset into
68
69
  # the receiver's options.
69
70
  def mutation_method(meth, *args, &block)
70
- raise_if_frozen!("#{meth}!")
71
+ raise_if_frozen!(["#{meth}!", meth])
71
72
  @opts = send(meth, *args, &block).opts
72
73
  @cache = {}
73
74
  self
@@ -78,7 +79,15 @@ module Sequel
78
79
  if frozen?
79
80
  raise RuntimeError, "can't modify frozen #{visible_class_name}"
80
81
  end
81
- Sequel::Deprecation.deprecate("Dataset mutation is deprecated and will be removed in Sequel 5#{" (method called: #{meth})" if meth}")
82
+ case meth
83
+ when Array
84
+ meth = " (method called: #{meth.first}, non-mutating replacement: #{meth.last})"
85
+ when String
86
+ # :nocov:
87
+ meth = " (method called: #{meth})"
88
+ # :nocov:
89
+ end
90
+ Sequel::Deprecation.deprecate("Dataset mutation is deprecated and will be removed in Sequel 5#{meth}")
82
91
  end
83
92
 
84
93
  # Set the dataset to skip the symbol cache
@@ -92,6 +92,7 @@ module Sequel
92
92
  Dataset.def_deprecated_opts_setter(self, :log_sql, :prepared_type, :prepared_args, :orig_dataset, :prepared_modify_values)
93
93
 
94
94
  PLACEHOLDER_RE = /\A\$(.*)\z/
95
+ Sequel::Deprecation.deprecate_constant(self, :PLACEHOLDER_RE)
95
96
 
96
97
  # Whether to log the full SQL query. By default, just the prepared statement
97
98
  # name is generally logged on adapters that support native prepared statements.
@@ -166,7 +167,7 @@ module Sequel
166
167
  # prepared_args is present. If so, they are considered placeholders,
167
168
  # and they are substituted using prepared_arg.
168
169
  def literal_symbol_append(sql, v)
169
- if @opts[:bind_vars] and match = PLACEHOLDER_RE.match(v.to_s)
170
+ if @opts[:bind_vars] and match = /\A\$(.*)\z/.match(v.to_s)
170
171
  s = match[1].to_sym
171
172
  if prepared_arg?(s)
172
173
  literal_append(sql, prepared_arg(s))
@@ -212,7 +213,7 @@ module Sequel
212
213
  when :insert_pk
213
214
  fetch_rows(prepared_sql){|r| return r.values.first}
214
215
  when Array
215
- case prepared_type.at(0)
216
+ case prepared_type[0]
216
217
  when :map, :to_hash, :to_hash_groups
217
218
  send(*prepared_type, &block)
218
219
  end
@@ -12,13 +12,15 @@ module Sequel
12
12
  # in the extension).
13
13
  EXTENSIONS = {}
14
14
 
15
+ EMPTY_ARRAY = [].freeze
16
+
15
17
  # The dataset options that require the removal of cached columns
16
18
  # if changed.
17
19
  COLUMN_CHANGE_OPTS = [:select, :sql, :from, :join].freeze
18
20
 
19
21
  # Which options don't affect the SQL generation. Used by simple_select_all?
20
22
  # to determine if this is a simple SELECT * FROM table.
21
- NON_SQL_OPTIONS = [:server, :graph, :eager, :eager_graph, :graph_aliases, :row_proc, :quote_identifiers, :identifier_input_method, :identifier_output_method, :skip_symbol_cache, :model, :model_object, :association_reflection, :fetch, :numrows, :autoid].freeze
23
+ NON_SQL_OPTIONS = [:server, :graph, :eager, :eager_graph, :graph_aliases, :row_proc, :quote_identifiers, :identifier_input_method, :identifier_output_method, :skip_symbol_cache, :model, :model_object, :association_reflection, :fetch, :numrows, :autoid].freeze # SEQUEL5: Remove graph_aliases
22
24
 
23
25
  # These symbols have _join methods created (e.g. inner_join) that
24
26
  # call join_table with the symbol, passing along the arguments and
@@ -91,7 +93,7 @@ module Sequel
91
93
  unless opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
92
94
  c.clear_columns_cache
93
95
  end
94
- c.freeze if frozen?
96
+ c.freeze if frozen? # SEQUEL5: Remove if frozen?
95
97
  c
96
98
  end
97
99
  else
@@ -102,7 +104,7 @@ module Sequel
102
104
  unless opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
103
105
  c.clear_columns_cache
104
106
  end
105
- c.freeze if frozen?
107
+ c.freeze if frozen? # SEQUEL5: c.opts.freeze
106
108
  c
107
109
  end
108
110
  # :nocov:
@@ -172,7 +174,7 @@ module Sequel
172
174
  # DB[:items].exclude(Sequel.~(:category=>nil) & {:category => 'software'})
173
175
  # # SELECT * FROM items WHERE ((category IS NULL) OR (category != 'software'))
174
176
  def exclude(*cond, &block)
175
- _filter_or_exclude(true, :where, *cond, &block)
177
+ add_filter(:where, cond, true, &block)
176
178
  end
177
179
 
178
180
  # Inverts the given conditions and adds them to the HAVING clause.
@@ -183,7 +185,7 @@ module Sequel
183
185
  # See documentation for exclude for how inversion is handled in regards
184
186
  # to SQL 3-valued boolean logic.
185
187
  def exclude_having(*cond, &block)
186
- _filter_or_exclude(true, :having, *cond, &block)
188
+ add_filter(:having, cond, true, &block)
187
189
  end
188
190
 
189
191
  # Alias for exclude.
@@ -198,7 +200,7 @@ module Sequel
198
200
  def extension(*a)
199
201
  c = _clone(:freeze=>false)
200
202
  c.send(:_extension!, a)
201
- c.freeze if frozen?
203
+ c.freeze if frozen? # SEQUEL5: Remove if frozen?
202
204
  c
203
205
  end
204
206
  else
@@ -258,7 +260,7 @@ module Sequel
258
260
  end
259
261
  end
260
262
  o = {:from=>source.empty? ? nil : source.freeze}
261
- o[:with] = ((opts[:with] || []) + ctes).freeze if ctes
263
+ o[:with] = ((opts[:with] || EMPTY_ARRAY) + ctes).freeze if ctes
262
264
  o[:num_dataset_sources] = table_alias_num if table_alias_num > 0
263
265
  clone(o)
264
266
  end
@@ -413,7 +415,7 @@ module Sequel
413
415
  # DB[:items].group(:sum).having(:sum=>10)
414
416
  # # SELECT * FROM items GROUP BY sum HAVING (sum = 10)
415
417
  def having(*cond, &block)
416
- _filter(:having, *cond, &block)
418
+ add_filter(:having, cond, &block)
417
419
  end
418
420
 
419
421
  # Adds an INTERSECT clause using a second dataset object.
@@ -542,8 +544,6 @@ module Sequel
542
544
  end
543
545
 
544
546
  table_alias = options[:table_alias]
545
- last_alias = options[:implicit_qualifier]
546
- qualify_type = options[:qualify]
547
547
 
548
548
  if table.is_a?(SQL::AliasedExpression)
549
549
  table_expr = if table_alias
@@ -573,7 +573,8 @@ module Sequel
573
573
  raise(Sequel::Error, "can't use a block if providing an array of symbols as expr") if block
574
574
  SQL::JoinUsingClause.new(expr, type, table_expr)
575
575
  else
576
- last_alias ||= @opts[:last_joined_table] || first_source_alias
576
+ last_alias = options[:implicit_qualifier] || @opts[:last_joined_table] || first_source_alias
577
+ qualify_type = options[:qualify]
577
578
  if Sequel.condition_specifier?(expr)
578
579
  expr = expr.collect do |k, v|
579
580
  qualify_type = default_join_table_qualification if qualify_type.nil?
@@ -592,13 +593,13 @@ module Sequel
592
593
  expr = SQL::BooleanExpression.from_value_pairs(expr)
593
594
  end
594
595
  if block
595
- expr2 = yield(table_name, last_alias, @opts[:join] || [])
596
+ expr2 = yield(table_name, last_alias, @opts[:join] || EMPTY_ARRAY)
596
597
  expr = expr ? SQL::BooleanExpression.new(:AND, expr, expr2) : expr2
597
598
  end
598
599
  SQL::JoinOnClause.new(expr, type, table_expr)
599
600
  end
600
601
 
601
- opts = {:join => ((@opts[:join] || []) + [join]).freeze}
602
+ opts = {:join => ((@opts[:join] || EMPTY_ARRAY) + [join]).freeze}
602
603
  opts[:last_joined_table] = table_name unless options[:reset_implicit_qualifier] == false
603
604
  opts[:num_dataset_sources] = table_alias_num if table_alias_num
604
605
  clone(opts)
@@ -694,17 +695,17 @@ module Sequel
694
695
  clone(:offset => o)
695
696
  end
696
697
 
697
- # Adds an alternate filter to an existing filter using OR. If no filter
698
- # exists an +Error+ is raised.
698
+ # Adds an alternate filter to an existing WHERE clause using OR. If there
699
+ # is no WHERE clause, then the default is WHERE true, and OR would be redundant,
700
+ # so return an unmodified clone of the dataset in that case.
699
701
  #
700
702
  # DB[:items].where(:a).or(:b) # SELECT * FROM items WHERE a OR b
703
+ # DB[:items].or(:b) # SELECT * FROM items
701
704
  def or(*cond, &block)
702
- cond = cond.first if cond.size == 1
703
- v = @opts[:where]
704
- if v.nil? || (cond.respond_to?(:empty?) && cond.empty? && !block)
705
+ if @opts[:where].nil?
705
706
  clone
706
707
  else
707
- clone(:where => SQL::BooleanExpression.new(:OR, v, filter_expr(cond, &block)))
708
+ add_filter(:where, cond, false, :OR, &block)
708
709
  end
709
710
  end
710
711
 
@@ -766,7 +767,7 @@ module Sequel
766
767
  # # SELECT i.* FROM items WHERE (i.id = 1)
767
768
  def qualify(table=first_source)
768
769
  o = @opts
769
- return clone if o[:sql]
770
+ return clone if o[:sql] # SEQUEL5: return self
770
771
  h = {}
771
772
  (o.keys & QUALIFY_KEYS).each do |k|
772
773
  h[k] = qualified_expression(o[k], table)
@@ -1030,7 +1031,7 @@ module Sequel
1030
1031
  #
1031
1032
  # See the {"Dataset Filtering" guide}[rdoc-ref:doc/dataset_filtering.rdoc] for more examples and details.
1032
1033
  def where(*cond, &block)
1033
- _filter(:where, *cond, &block)
1034
+ add_filter(:where, cond, &block)
1034
1035
  end
1035
1036
 
1036
1037
  # Add a common table expression (CTE) with the given name and a dataset that defines the CTE.
@@ -1047,7 +1048,7 @@ module Sequel
1047
1048
  s, ds = hoist_cte(dataset)
1048
1049
  s.with(name, ds, opts)
1049
1050
  else
1050
- clone(:with=>((@opts[:with]||[]) + [Hash[opts].merge!(:name=>name, :dataset=>dataset)]).freeze)
1051
+ clone(:with=>((@opts[:with]||EMPTY_ARRAY) + [Hash[opts].merge!(:name=>name, :dataset=>dataset)]).freeze)
1051
1052
  end
1052
1053
  end
1053
1054
 
@@ -1076,7 +1077,7 @@ module Sequel
1076
1077
  s, ds = hoist_cte(recursive)
1077
1078
  s.with_recursive(name, nonrecursive, ds, opts)
1078
1079
  else
1079
- clone(:with=>((@opts[:with]||[]) + [Hash[opts].merge!(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))]).freeze)
1080
+ clone(:with=>((@opts[:with]||EMPTY_ARRAY) + [Hash[opts].merge!(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))]).freeze)
1080
1081
  end
1081
1082
  end
1082
1083
 
@@ -1090,7 +1091,7 @@ module Sequel
1090
1091
  c = _clone(:freeze=>false)
1091
1092
  c.extend(*mods) unless mods.empty?
1092
1093
  c.extend(Module.new(&block)) if block
1093
- c.freeze if frozen?
1094
+ c.freeze if frozen? # SEQUEL5: Remove if frozen?
1094
1095
  c
1095
1096
  end
1096
1097
  else
@@ -1171,14 +1172,21 @@ module Sequel
1171
1172
  !(@opts.collect{|k,v| k unless v.nil?}.compact & opts).empty?
1172
1173
  end
1173
1174
 
1175
+ # From types allowed to be considered a simple_select_all
1176
+ SIMPLE_SELECT_ALL_ALLOWED_FROM = [Symbol, SQL::Identifier, SQL::QualifiedIdentifier].freeze
1177
+
1174
1178
  # Whether this dataset is a simple select from an underlying table, such as:
1175
1179
  #
1176
1180
  # SELECT * FROM table
1177
1181
  # SELECT table.* FROM table
1178
1182
  def simple_select_all?
1183
+ return false unless (f = @opts[:from]) && f.length == 1
1179
1184
  non_sql = non_sql_options
1180
1185
  o = @opts.reject{|k,v| v.nil? || non_sql.include?(k)}
1181
- if (f = o[:from]) && f.length == 1 && (f.first.is_a?(Symbol) || f.first.is_a?(SQL::AliasedExpression))
1186
+ from = f.first
1187
+ from = from.expression if from.is_a?(SQL::AliasedExpression)
1188
+
1189
+ if SIMPLE_SELECT_ALL_ALLOWED_FROM.any?{|x| from.is_a?(x)}
1182
1190
  case o.length
1183
1191
  when 1
1184
1192
  true
@@ -1207,24 +1215,54 @@ module Sequel
1207
1215
  self
1208
1216
  end
1209
1217
 
1210
- # Internal filtering method so it works on either the WHERE or HAVING clauses, with or
1211
- # without inversion.
1212
- def _filter_or_exclude(invert, clause, *cond, &block)
1218
+ def add_filter(clause, cond, invert=false, combine=:AND, &block)
1219
+ if cond == EMPTY_ARRAY && !block
1220
+ Sequel::Deprecation.deprecate("Passing no arguments and no block to a filtering method", "Include at least one argument or a block when calling a filtering method")
1221
+ #raise Error, "must provide an argument to a filtering method if not passing a block" # SEQUEL5
1222
+ end
1223
+
1213
1224
  cond = cond.first if cond.size == 1
1214
- if cond.respond_to?(:empty?) && cond.empty? && !block
1225
+
1226
+ empty = cond == OPTS || cond == EMPTY_ARRAY
1227
+ old_empty = cond.respond_to?(:empty?) && cond.empty?
1228
+ if old_empty && !empty
1229
+ Sequel::Deprecation.deprecate("Treating #{cond.inspect} as a empty filter expression", "Only {} and [] are considered empty expressions now")
1230
+ empty = true
1231
+ end
1232
+
1233
+ if empty && !block
1215
1234
  clone
1216
1235
  else
1236
+ if cond == nil
1237
+ if block
1238
+ Sequel::Deprecation.deprecate("Ignoring explicit nil argument when passing a block to a filtering method", "Do not pass an explicit nil argument to the filtering method, only pass the block")
1239
+ end
1240
+ unless @opts[clause]
1241
+ Sequel::Deprecation.deprecate("Ignoring explicit nil argument to a filtering method if dataset has no explicit filter", "Starting in Sequel 5, this will add a NULL condition")
1242
+ end
1243
+ #cond = Sequel::NULL # SEQUEL5
1244
+ end
1245
+ if empty && block
1246
+ cond = nil
1247
+ end
1248
+
1217
1249
  cond = filter_expr(cond, &block)
1218
1250
  cond = SQL::BooleanExpression.invert(cond) if invert
1219
- cond = SQL::BooleanExpression.new(:AND, @opts[clause], cond) if @opts[clause]
1251
+ cond = SQL::BooleanExpression.new(combine, @opts[clause], cond) if @opts[clause]
1220
1252
  clone(clause => cond)
1221
1253
  end
1222
1254
  end
1223
1255
 
1224
- # Internal filter method so it works on either the having or where clauses.
1256
+ # :nocov:
1257
+ def _filter_or_exclude(invert, clause, *cond, &block)
1258
+ Sequel::Deprecation.deprecate("Sequel::Dataset#_filter/_filter_or_exclude (private methods)", "Switch to calling a public dataset filtering method directly")
1259
+ add_filter(clause, cond, invert, &block)
1260
+ end
1261
+
1225
1262
  def _filter(clause, *cond, &block)
1226
1263
  _filter_or_exclude(false, clause, *cond, &block)
1227
1264
  end
1265
+ # :nocov:
1228
1266
 
1229
1267
  # The default :qualify option to use for join tables if one is not specified.
1230
1268
  def default_join_table_qualification
@@ -1233,7 +1271,7 @@ module Sequel
1233
1271
 
1234
1272
  # SQL expression object based on the expr type. See +where+.
1235
1273
  def filter_expr(expr = nil, &block)
1236
- expr = nil if expr == []
1274
+ expr = nil if expr == EMPTY_ARRAY
1237
1275
 
1238
1276
  if block
1239
1277
  if expr
@@ -1247,10 +1285,13 @@ module Sequel
1247
1285
  when Hash
1248
1286
  SQL::BooleanExpression.from_value_pairs(expr)
1249
1287
  when Array
1250
- if (sexpr = expr.at(0)).is_a?(String)
1251
- SQL::PlaceholderLiteralString.new(sexpr, expr[1..-1], true)
1252
- elsif Sequel.condition_specifier?(expr)
1288
+ if Sequel.condition_specifier?(expr)
1253
1289
  SQL::BooleanExpression.from_value_pairs(expr)
1290
+ #else # SEQUEL5
1291
+ # raise(Error, "Invalid filter expression: #{expr.inspect}")
1292
+ elsif (sexpr = expr[0]).is_a?(String)
1293
+ Sequel::Deprecation.deprecate("Calling a dataset filtering method with multiple arguments or an array where the first argument/element is a string", "Use Sequel.lit(#{sexpr.inspect}#{", #{expr[1..-1].map(&:inspect).join(', ')}" if expr.length > 1}) to create an SQL fragment expression and pass that to the dataset filtering method, or use the auto_literal_strings extension")
1294
+ SQL::PlaceholderLiteralString.new(sexpr, expr[1..-1], true)
1254
1295
  else
1255
1296
  Sequel::Deprecation.deprecate("Passing multiple arguments as filter arguments when not using a conditions specifier (#{expr.inspect})", "Pass the arguments to separate filter methods or use Sequel.& to combine them")
1256
1297
  SQL::BooleanExpression.new(:AND, *expr.map{|x| filter_expr(x)})
@@ -1258,7 +1299,9 @@ module Sequel
1258
1299
  when Proc
1259
1300
  Sequel::Deprecation.deprecate("Passing Proc objects as filter arguments", "Pass them as blocks to the filtering methods or to Sequel.expr")
1260
1301
  filter_expr(Sequel.virtual_row(&expr))
1261
- when Numeric, SQL::NumericExpression, SQL::StringExpression #, Proc # SEQUEL5
1302
+ when LiteralString
1303
+ LiteralString.new("(#{expr})")
1304
+ when Numeric, SQL::NumericExpression, SQL::StringExpression #, Proc, String # SEQUEL5
1262
1305
  raise(Error, "Invalid filter expression: #{expr.inspect}")
1263
1306
  when TrueClass, FalseClass
1264
1307
  if supports_where_true?
@@ -1269,9 +1312,12 @@ module Sequel
1269
1312
  SQL::Constants::SQLFALSE
1270
1313
  end
1271
1314
  when String
1315
+ Sequel::Deprecation.deprecate("Calling a dataset filtering method with a plain string", "Use Sequel.lit(#{expr.inspect}) to create a literal string and pass that to the dataset filtering method, or use the auto_literal_strings extension")
1272
1316
  LiteralString.new("(#{expr})")
1273
1317
  when PlaceholderLiteralizer::Argument
1274
1318
  expr.transform{|v| filter_expr(v)}
1319
+ when SQL::PlaceholderLiteralString
1320
+ expr.with_parens
1275
1321
  else
1276
1322
  expr
1277
1323
  end
@@ -1281,7 +1327,7 @@ module Sequel
1281
1327
  # clause from the given dataset added to it, and the second a clone of
1282
1328
  # the given dataset with the WITH clause removed.
1283
1329
  def hoist_cte(ds)
1284
- [clone(:with => ((opts[:with] || []) + ds.opts[:with]).freeze), ds.clone(:with => nil)]
1330
+ [clone(:with => ((opts[:with] || EMPTY_ARRAY) + ds.opts[:with]).freeze), ds.clone(:with => nil)]
1285
1331
  end
1286
1332
 
1287
1333
  # Whether CTEs need to be hoisted from the given ds into the current ds.
@@ -1295,7 +1341,7 @@ module Sequel
1295
1341
  # DB[:items].invert_order([Sequel.desc(:id)]]) #=> [Sequel.asc(:id)]
1296
1342
  # DB[:items].invert_order([:category, Sequel.desc(:price)]) #=> [Sequel.desc(:category), Sequel.asc(:price)]
1297
1343
  def invert_order(order)
1298
- return nil unless order
1344
+ return unless order
1299
1345
  order.map do |f|
1300
1346
  case f
1301
1347
  when SQL::OrderedExpression