sequel 5.8.0 → 5.38.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 (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -81,7 +81,9 @@ module Sequel
81
81
  # If the options changed include options in COLUMN_CHANGE_OPTS, the cached
82
82
  # columns are deleted. This method should generally not be called
83
83
  # directly by user code.
84
- def clone(opts = (return self; nil))
84
+ def clone(opts = nil || (return self))
85
+ # return self used above because clone is called by almost all
86
+ # other query methods, and it is the fastest approach
85
87
  c = super(:freeze=>false)
86
88
  c.opts.merge!(opts)
87
89
  unless opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
@@ -113,6 +115,11 @@ module Sequel
113
115
  # DB[:items].distinct # SQL: SELECT DISTINCT * FROM items
114
116
  # DB[:items].order(:id).distinct(:id) # SQL: SELECT DISTINCT ON (id) * FROM items ORDER BY id
115
117
  # DB[:items].order(:id).distinct{func(:id)} # SQL: SELECT DISTINCT ON (func(id)) * FROM items ORDER BY id
118
+ #
119
+ # There is support for emualting the DISTINCT ON support in MySQL, but it
120
+ # does not support the ORDER of the dataset, and also doesn't work in many
121
+ # cases if the ONLY_FULL_GROUP_BY sql_mode is used, which is the default on
122
+ # MySQL 5.7.5+.
116
123
  def distinct(*args, &block)
117
124
  virtual_row_columns(args, block)
118
125
  if args.empty?
@@ -284,7 +291,7 @@ module Sequel
284
291
  c
285
292
  end
286
293
 
287
- cache ? cached_dataset(:_from_self_ds, &pr) : pr.call
294
+ opts.empty? ? cached_dataset(:_from_self_ds, &pr) : pr.call
288
295
  end
289
296
 
290
297
  # Match any of the columns to any of the patterns. The terms can be
@@ -323,16 +330,17 @@ module Sequel
323
330
  # # SELECT * FROM a WHERE ((a LIKE '%foo%' ESCAPE '\') AND (b LIKE '%foo%' ESCAPE '\')
324
331
  # # AND (a LIKE '%bar%' ESCAPE '\') AND (b LIKE '%bar%' ESCAPE '\'))
325
332
  def grep(columns, patterns, opts=OPTS)
333
+ column_op = opts[:all_columns] ? :AND : :OR
326
334
  if opts[:all_patterns]
327
335
  conds = Array(patterns).map do |pat|
328
- SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
336
+ SQL::BooleanExpression.new(column_op, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
329
337
  end
330
- where(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
338
+ where(SQL::BooleanExpression.new(:AND, *conds))
331
339
  else
332
340
  conds = Array(columns).map do |c|
333
341
  SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
334
342
  end
335
- where(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
343
+ where(SQL::BooleanExpression.new(column_op, *conds))
336
344
  end
337
345
  end
338
346
 
@@ -1039,12 +1047,26 @@ module Sequel
1039
1047
  add_filter(:where, cond, &block)
1040
1048
  end
1041
1049
 
1050
+ # Return a clone of the dataset with an addition named window that can be
1051
+ # referenced in window functions. See Sequel::SQL::Window for a list of
1052
+ # options that can be passed in. Example:
1053
+ #
1054
+ # DB[:items].window(:w, :partition=>:c1, :order=>:c2)
1055
+ # # SELECT * FROM items WINDOW w AS (PARTITION BY c1 ORDER BY c2)
1056
+ def window(name, opts)
1057
+ clone(:window=>((@opts[:window]||EMPTY_ARRAY) + [[name, SQL::Window.new(opts)].freeze]).freeze)
1058
+ end
1059
+
1042
1060
  # Add a common table expression (CTE) with the given name and a dataset that defines the CTE.
1043
1061
  # A common table expression acts as an inline view for the query.
1044
1062
  # Options:
1045
1063
  # :args :: Specify the arguments/columns for the CTE, should be an array of symbols.
1046
1064
  # :recursive :: Specify that this is a recursive CTE
1047
1065
  #
1066
+ # PostgreSQL Specific Options:
1067
+ # :materialized :: Set to false to force inlining of the CTE, or true to force not inlining
1068
+ # the CTE (PostgreSQL 12+).
1069
+ #
1048
1070
  # DB[:items].with(:items, DB[:syx].where(Sequel[:name].like('A%')))
1049
1071
  # # WITH items AS (SELECT * FROM syx WHERE (name LIKE 'A%' ESCAPE '\')) SELECT * FROM items
1050
1072
  def with(name, dataset, opts=OPTS)
@@ -1074,7 +1096,7 @@ module Sequel
1074
1096
  # # SELECT i1.id, i1.parent_id FROM i1 INNER JOIN t ON (t.id = i1.parent_id)
1075
1097
  # # ) SELECT * FROM t
1076
1098
  def with_recursive(name, nonrecursive, recursive, opts=OPTS)
1077
- raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
1099
+ raise(Error, 'This dataset does not support common table expressions') unless supports_cte?
1078
1100
  if hoist_cte?(nonrecursive)
1079
1101
  s, ds = hoist_cte(nonrecursive)
1080
1102
  s.with_recursive(name, ds, recursive, opts)
@@ -1216,6 +1238,20 @@ module Sequel
1216
1238
  self
1217
1239
  end
1218
1240
 
1241
+ # If invert is true, invert the condition.
1242
+ def _invert_filter(cond, invert)
1243
+ if invert
1244
+ SQL::BooleanExpression.invert(cond)
1245
+ else
1246
+ cond
1247
+ end
1248
+ end
1249
+
1250
+ # Add the given filter condition. Arguments:
1251
+ # clause :: Symbol or which SQL clause to effect, should be :where or :having
1252
+ # cond :: The filter condition to add
1253
+ # invert :: Whether the condition should be inverted (true or false)
1254
+ # combine :: How to combine the condition with an existing condition, should be :AND or :OR
1219
1255
  def add_filter(clause, cond, invert=false, combine=:AND, &block)
1220
1256
  if cond == EMPTY_ARRAY && !block
1221
1257
  raise Error, "must provide an argument to a filtering method if not passing a block"
@@ -1235,8 +1271,7 @@ module Sequel
1235
1271
  cond = nil
1236
1272
  end
1237
1273
 
1238
- cond = filter_expr(cond, &block)
1239
- cond = SQL::BooleanExpression.invert(cond) if invert
1274
+ cond = _invert_filter(filter_expr(cond, &block), invert)
1240
1275
  cond = SQL::BooleanExpression.new(combine, @opts[clause], cond) if @opts[clause]
1241
1276
 
1242
1277
  if cond.nil?
@@ -28,7 +28,7 @@ module Sequel
28
28
 
29
29
  case values.size
30
30
  when 0
31
- return insert_sql({})
31
+ return insert_sql(OPTS)
32
32
  when 1
33
33
  case vals = values[0]
34
34
  when Hash
@@ -389,8 +389,10 @@ module Sequel
389
389
  literal_append(sql, args[0])
390
390
  sql << ' ' << op.to_s << ' '
391
391
  literal_append(sql, args[1])
392
- sql << " ESCAPE "
393
- literal_append(sql, "\\")
392
+ if requires_like_escape?
393
+ sql << " ESCAPE "
394
+ literal_append(sql, "\\")
395
+ end
394
396
  sql << ')'
395
397
  when :ILIKE, :'NOT ILIKE'
396
398
  complex_expression_sql_append(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|v| Sequel.function(:UPPER, v)})
@@ -490,11 +492,24 @@ module Sequel
490
492
  end
491
493
 
492
494
  sql << '('
495
+ if filter = opts[:filter]
496
+ filter = filter_expr(filter, &opts[:filter_block])
497
+ end
493
498
  if opts[:*]
494
- sql << '*'
499
+ if filter && !supports_filtered_aggregates?
500
+ literal_append(sql, Sequel.case({filter=>1}, nil))
501
+ filter = nil
502
+ else
503
+ sql << '*'
504
+ end
495
505
  else
496
506
  sql << "DISTINCT " if opts[:distinct]
497
- expression_list_append(sql, f.args)
507
+ if filter && !supports_filtered_aggregates?
508
+ expression_list_append(sql, f.args.map{|arg| Sequel.case({filter=>arg}, nil)})
509
+ filter = nil
510
+ else
511
+ expression_list_append(sql, f.args)
512
+ end
498
513
  if order = opts[:order]
499
514
  sql << " ORDER BY "
500
515
  expression_list_append(sql, order)
@@ -508,9 +523,9 @@ module Sequel
508
523
  sql << ')'
509
524
  end
510
525
 
511
- if filter = opts[:filter]
526
+ if filter
512
527
  sql << " FILTER (WHERE "
513
- literal_append(sql, filter_expr(filter, &opts[:filter_block]))
528
+ literal_append(sql, filter)
514
529
  sql << ')'
515
530
  end
516
531
 
@@ -557,13 +572,30 @@ module Sequel
557
572
 
558
573
  # Append literalization of ordered expression to SQL string.
559
574
  def ordered_expression_sql_append(sql, oe)
575
+ if emulate = requires_emulating_nulls_first?
576
+ case oe.nulls
577
+ when :first
578
+ null_order = 0
579
+ when :last
580
+ null_order = 2
581
+ end
582
+
583
+ if null_order
584
+ literal_append(sql, Sequel.case({{oe.expression=>nil}=>null_order}, 1))
585
+ sql << ", "
586
+ end
587
+ end
588
+
560
589
  literal_append(sql, oe.expression)
561
590
  sql << (oe.descending ? ' DESC' : ' ASC')
562
- case oe.nulls
563
- when :first
564
- sql << " NULLS FIRST"
565
- when :last
566
- sql << " NULLS LAST"
591
+
592
+ unless emulate
593
+ case oe.nulls
594
+ when :first
595
+ sql << " NULLS FIRST"
596
+ when :last
597
+ sql << " NULLS LAST"
598
+ end
567
599
  end
568
600
  end
569
601
 
@@ -577,7 +609,7 @@ module Sequel
577
609
  sql << str
578
610
  else
579
611
  re = /:(#{args.keys.map{|k| Regexp.escape(k.to_s)}.join('|')})\b/
580
- loop do
612
+ while true
581
613
  previous, q, str = str.partition(re)
582
614
  sql << previous
583
615
  literal_append(sql, args[($1||q[1..-1].to_s).to_sym]) unless q.empty?
@@ -596,13 +628,13 @@ module Sequel
596
628
  else
597
629
  i = -1
598
630
  match_len = args.length - 1
599
- loop do
631
+ while true
600
632
  previous, q, str = str.partition('?')
601
633
  sql << previous
602
634
  literal_append(sql, args.at(i+=1)) unless q.empty?
603
635
  if str.empty?
604
636
  unless i == match_len
605
- raise Error, "Mismatched number of placeholders (#{i+1}) and placeholder arguments (#{args.length}) when using placeholder array"
637
+ raise Error, "Mismatched number of placeholders (#{i+1}) and placeholder arguments (#{args.length}) when using placeholder string"
606
638
  end
607
639
  break
608
640
  end
@@ -698,8 +730,19 @@ module Sequel
698
730
 
699
731
  # Append literalization of subscripts (SQL array accesses) to SQL string.
700
732
  def subscript_sql_append(sql, s)
733
+ case s.expression
734
+ when Symbol, SQL::Subscript, SQL::Identifier, SQL::QualifiedIdentifier
735
+ # nothing
736
+ else
737
+ wrap_expression = true
738
+ sql << '('
739
+ end
701
740
  literal_append(sql, s.expression)
702
- sql << '['
741
+ if wrap_expression
742
+ sql << ')['
743
+ else
744
+ sql << '['
745
+ end
703
746
  sub = s.sub
704
747
  if sub.length == 1 && (range = sub.first).is_a?(Range)
705
748
  literal_append(sql, range.begin)
@@ -716,41 +759,86 @@ module Sequel
716
759
  # Append literalization of windows (for window functions) to SQL string.
717
760
  def window_sql_append(sql, opts)
718
761
  raise(Error, 'This dataset does not support window functions') unless supports_window_functions?
719
- sql << '('
720
- window, part, order, frame = opts.values_at(:window, :partition, :order, :frame)
721
762
  space = false
722
763
  space_s = ' '
723
- if window
764
+
765
+ sql << '('
766
+
767
+ if window = opts[:window]
724
768
  literal_append(sql, window)
725
769
  space = true
726
770
  end
727
- if part
771
+
772
+ if part = opts[:partition]
728
773
  sql << space_s if space
729
774
  sql << "PARTITION BY "
730
775
  expression_list_append(sql, Array(part))
731
776
  space = true
732
777
  end
733
- if order
778
+
779
+ if order = opts[:order]
734
780
  sql << space_s if space
735
781
  sql << "ORDER BY "
736
782
  expression_list_append(sql, Array(order))
737
783
  space = true
738
784
  end
739
- case frame
740
- when nil
741
- # nothing
742
- when :all
743
- sql << space_s if space
744
- sql << "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
745
- when :rows
746
- sql << space_s if space
747
- sql << "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"
748
- when String
749
- sql << space_s if space
785
+
786
+ if frame = opts[:frame]
787
+ sql << space_s if space
788
+
789
+ if frame.is_a?(String)
750
790
  sql << frame
751
791
  else
752
- raise Error, "invalid window frame clause, should be :all, :rows, a string, or nil"
792
+ case frame
793
+ when :all
794
+ frame_type = :rows
795
+ frame_start = :preceding
796
+ frame_end = :following
797
+ when :rows, :range, :groups
798
+ frame_type = frame
799
+ frame_start = :preceding
800
+ frame_end = :current
801
+ when Hash
802
+ frame_type = frame[:type]
803
+ unless frame_type == :rows || frame_type == :range || frame_type == :groups
804
+ raise Error, "invalid window :frame :type option: #{frame_type.inspect}"
805
+ end
806
+ unless frame_start = frame[:start]
807
+ raise Error, "invalid window :frame :start option: #{frame_start.inspect}"
808
+ end
809
+ frame_end = frame[:end]
810
+ frame_exclude = frame[:exclude]
811
+ else
812
+ raise Error, "invalid window :frame option: #{frame.inspect}"
813
+ end
814
+
815
+ sql << frame_type.to_s.upcase << " "
816
+ sql << 'BETWEEN ' if frame_end
817
+ window_frame_boundary_sql_append(sql, frame_start, :preceding)
818
+ if frame_end
819
+ sql << " AND "
820
+ window_frame_boundary_sql_append(sql, frame_end, :following)
821
+ end
822
+
823
+ if frame_exclude
824
+ sql << " EXCLUDE "
825
+
826
+ case frame_exclude
827
+ when :current
828
+ sql << "CURRENT ROW"
829
+ when :group
830
+ sql << "GROUP"
831
+ when :ties
832
+ sql << "TIES"
833
+ when :no_others
834
+ sql << "NO OTHERS"
835
+ else
836
+ raise Error, "invalid window :frame :exclude option: #{frame_exclude.inspect}"
837
+ end
838
+ end
839
+ end
753
840
  end
841
+
754
842
  sql << ')'
755
843
  end
756
844
 
@@ -1410,6 +1498,22 @@ module Sequel
1410
1498
  alias delete_where_sql select_where_sql
1411
1499
  alias update_where_sql select_where_sql
1412
1500
 
1501
+ def select_window_sql(sql)
1502
+ if ws = @opts[:window]
1503
+ sql << " WINDOW "
1504
+ c = false
1505
+ co = ', '
1506
+ as = ' AS '
1507
+ ws.map do |name, window|
1508
+ sql << co if c
1509
+ literal_append(sql, name)
1510
+ sql << as
1511
+ literal_append(sql, window)
1512
+ c ||= true
1513
+ end
1514
+ end
1515
+ end
1516
+
1413
1517
  def select_with_sql(sql)
1414
1518
  return unless supports_cte?
1415
1519
  ws = opts[:with]
@@ -1419,13 +1523,7 @@ module Sequel
1419
1523
  comma = ', '
1420
1524
  ws.each do |w|
1421
1525
  sql << comma if c
1422
- quote_identifier_append(sql, w[:name])
1423
- if args = w[:args]
1424
- sql << '('
1425
- identifier_list_append(sql, args)
1426
- sql << ')'
1427
- end
1428
- sql << ' AS '
1526
+ select_with_sql_prefix(sql, w)
1429
1527
  literal_dataset_append(sql, w[:dataset])
1430
1528
  c ||= true
1431
1529
  end
@@ -1439,6 +1537,16 @@ module Sequel
1439
1537
  "WITH "
1440
1538
  end
1441
1539
 
1540
+ def select_with_sql_prefix(sql, w)
1541
+ quote_identifier_append(sql, w[:name])
1542
+ if args = w[:args]
1543
+ sql << '('
1544
+ identifier_list_append(sql, args)
1545
+ sql << ')'
1546
+ end
1547
+ sql << ' AS '
1548
+ end
1549
+
1442
1550
  # Whether the symbol cache should be skipped when literalizing the dataset
1443
1551
  def skip_symbol_cache?
1444
1552
  @opts[:skip_symbol_cache]
@@ -1490,7 +1598,17 @@ module Sequel
1490
1598
 
1491
1599
  # Append literalization of the subselect to SQL string.
1492
1600
  def subselect_sql_append(sql, ds)
1493
- ds.clone(:append_sql=>sql).sql
1601
+ sds = subselect_sql_dataset(sql, ds)
1602
+ sds.sql
1603
+ unless sds.send(:cache_sql?)
1604
+ # If subquery dataset does not allow caching SQL,
1605
+ # then this dataset should not allow caching SQL.
1606
+ disable_sql_caching!
1607
+ end
1608
+ end
1609
+
1610
+ def subselect_sql_dataset(sql, ds)
1611
+ ds.clone(:append_sql=>sql)
1494
1612
  end
1495
1613
 
1496
1614
  # The number of decimal digits of precision to use in timestamps.
@@ -1533,5 +1651,35 @@ module Sequel
1533
1651
  def update_update_sql(sql)
1534
1652
  sql << 'UPDATE'
1535
1653
  end
1654
+
1655
+ def window_frame_boundary_sql_append(sql, boundary, direction)
1656
+ case boundary
1657
+ when :current
1658
+ sql << "CURRENT ROW"
1659
+ when :preceding
1660
+ sql << "UNBOUNDED PRECEDING"
1661
+ when :following
1662
+ sql << "UNBOUNDED FOLLOWING"
1663
+ else
1664
+ if boundary.is_a?(Array)
1665
+ offset, direction = boundary
1666
+ unless boundary.length == 2 && (direction == :preceding || direction == :following)
1667
+ raise Error, "invalid window :frame boundary (:start or :end) option: #{boundary.inspect}"
1668
+ end
1669
+ else
1670
+ offset = boundary
1671
+ end
1672
+
1673
+ case offset
1674
+ when Numeric, String, SQL::Cast
1675
+ # nothing
1676
+ else
1677
+ raise Error, "invalid window :frame boundary (:start or :end) option: #{boundary.inspect}"
1678
+ end
1679
+
1680
+ literal_append(sql, offset)
1681
+ sql << (direction == :preceding ? " PRECEDING" : " FOLLOWING")
1682
+ end
1683
+ end
1536
1684
  end
1537
1685
  end