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
@@ -15,6 +15,12 @@ begin
15
15
  end
16
16
 
17
17
  Sequel::Postgres::USES_PG = true
18
+ if defined?(PG::TypeMapByClass)
19
+ type_map = Sequel::Postgres::PG_QUERY_TYPE_MAP = PG::TypeMapByClass.new
20
+ type_map[Integer] = PG::TextEncoder::Integer.new
21
+ type_map[FalseClass] = type_map[TrueClass] = PG::TextEncoder::Boolean.new
22
+ type_map[Float] = PG::TextEncoder::Float.new
23
+ end
18
24
  rescue LoadError => e
19
25
  begin
20
26
  require 'postgres-pr/postgres-compat'
@@ -64,6 +70,10 @@ module Sequel
64
70
  # string names of the server side prepared statement, and values
65
71
  # are SQL strings.
66
72
  attr_reader :prepared_statements
73
+
74
+ unless public_method_defined?(:async_exec_params)
75
+ alias async_exec_params async_exec
76
+ end
67
77
  else
68
78
  # Make postgres-pr look like pg
69
79
  CONNECTION_OK = -1
@@ -143,7 +153,7 @@ module Sequel
143
153
 
144
154
  # Return the PGResult containing the query results.
145
155
  def execute_query(sql, args)
146
- @db.log_connection_yield(sql, self, args){args ? async_exec(sql, args) : async_exec(sql)}
156
+ @db.log_connection_yield(sql, self, args){args ? async_exec_params(sql, args) : async_exec(sql)}
147
157
  end
148
158
  end
149
159
 
@@ -167,6 +177,15 @@ module Sequel
167
177
  end
168
178
  end
169
179
 
180
+ # Call a procedure with the given name and arguments. Returns a hash if the procedure
181
+ # returns a value, and nil otherwise. Example:
182
+ #
183
+ # DB.call_procedure(:foo, 1, 2)
184
+ # # CALL foo(1, 2)
185
+ def call_procedure(name, *args)
186
+ dataset.send(:call_procedure, name, args)
187
+ end
188
+
170
189
  # Connects to the database. In addition to the standard database
171
190
  # options, using the :encoding or :charset option changes the
172
191
  # client encoding for the connection, :connect_timeout is a
@@ -179,7 +198,7 @@ module Sequel
179
198
  if USES_PG
180
199
  connection_params = {
181
200
  :host => opts[:host],
182
- :port => opts[:port] || 5432,
201
+ :port => opts[:port],
183
202
  :dbname => opts[:database],
184
203
  :user => opts[:user],
185
204
  :password => opts[:password],
@@ -188,7 +207,7 @@ module Sequel
188
207
  :sslrootcert => opts[:sslrootcert]
189
208
  }.delete_if { |key, value| blank_object?(value) }
190
209
  connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
191
- conn = Adapter.connect(connection_params)
210
+ conn = Adapter.connect(opts[:conn_str] || connection_params)
192
211
 
193
212
  conn.instance_variable_set(:@prepared_statements, {})
194
213
 
@@ -211,6 +230,9 @@ module Sequel
211
230
  end
212
231
 
213
232
  conn.instance_variable_set(:@db, self)
233
+ if USES_PG && conn.respond_to?(:type_map_for_queries=) && defined?(PG_QUERY_TYPE_MAP)
234
+ conn.type_map_for_queries = PG_QUERY_TYPE_MAP
235
+ end
214
236
 
215
237
  if encoding = opts[:encoding] || opts[:charset]
216
238
  if conn.respond_to?(:set_client_encoding)
@@ -271,7 +293,7 @@ module Sequel
271
293
  def error_info(e)
272
294
  e = e.wrapped_exception if e.is_a?(DatabaseError)
273
295
  r = e.result
274
- h = {
296
+ {
275
297
  :schema => r.error_field(::PG::PG_DIAG_SCHEMA_NAME),
276
298
  :table => r.error_field(::PG::PG_DIAG_TABLE_NAME),
277
299
  :column => r.error_field(::PG::PG_DIAG_COLUMN_NAME),
@@ -449,7 +471,7 @@ module Sequel
449
471
  raise Error, 'calling #listen with :loop requires a block' unless block
450
472
  loop_call = l.respond_to?(:call)
451
473
  catch(:stop) do
452
- loop do
474
+ while true
453
475
  t = timeout_block ? [timeout_block.call] : []
454
476
  conn.wait_for_notify(*t, &block)
455
477
  l.call(conn) if loop_call
@@ -490,7 +512,7 @@ module Sequel
490
512
  @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, true))
491
513
  initialize_postgres_adapter
492
514
  add_conversion_proc(17, method(:unescape_bytea)) if USES_PG
493
- add_conversion_proc(1082, TYPE_TRANSLATOR.method(:date)) if @use_iso_date_format
515
+ add_conversion_proc(1082, TYPE_TRANSLATOR_DATE) if @use_iso_date_format
494
516
  self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
495
517
  end
496
518
 
@@ -594,6 +616,9 @@ module Sequel
594
616
 
595
617
  # Use a cursor for paging.
596
618
  def paged_each(opts=OPTS, &block)
619
+ unless block_given?
620
+ return enum_for(:paged_each, opts)
621
+ end
597
622
  use_cursor(opts).each(&block)
598
623
  end
599
624
 
@@ -663,11 +688,6 @@ module Sequel
663
688
  end
664
689
  LiteralString.new("#{prepared_arg_placeholder}#{i}")
665
690
  end
666
-
667
- # Always assume a prepared argument.
668
- def prepared_arg?(k)
669
- true
670
- end
671
691
  end
672
692
 
673
693
  BindArgumentMethods = prepared_statements_module(:bind, [ArgumentMapper], %w'execute execute_dui')
@@ -692,6 +712,15 @@ module Sequel
692
712
 
693
713
  private
694
714
 
715
+ # Generate and execute a procedure call.
716
+ def call_procedure(name, args)
717
+ sql = String.new
718
+ sql << "CALL "
719
+ identifier_append(sql, name)
720
+ literal_append(sql, args)
721
+ with_sql_first(sql)
722
+ end
723
+
695
724
  # Use a cursor to fetch groups of records at a time, yielding them to the block.
696
725
  def cursor_fetch_rows(sql)
697
726
  server_opts = {:server=>@opts[:server] || :read_only}
@@ -712,7 +741,7 @@ module Sequel
712
741
  yield_hash_rows(res, cols){|h| yield h}
713
742
  return if res.ntuples < rows_per_fetch
714
743
  end
715
- loop do
744
+ while true
716
745
  execute(fetch_sql) do |res|
717
746
  yield_hash_rows(res, cols){|h| yield h}
718
747
  return if res.ntuples < rows_per_fetch
@@ -737,9 +766,9 @@ module Sequel
737
766
  cols = []
738
767
  procs = db.conversion_procs
739
768
  res.nfields.times do |fieldnum|
740
- cols << [fieldnum, procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
769
+ cols << [procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
741
770
  end
742
- self.columns = cols.map{|c| c[2]}
771
+ self.columns = cols.map{|c| c[1]}
743
772
  cols
744
773
  end
745
774
 
@@ -756,13 +785,20 @@ module Sequel
756
785
  # For each row in the result set, yield a hash with column name symbol
757
786
  # keys and typecasted values.
758
787
  def yield_hash_rows(res, cols)
759
- res.ntuples.times do |recnum|
788
+ ntuples = res.ntuples
789
+ recnum = 0
790
+ while recnum < ntuples
791
+ fieldnum = 0
792
+ nfields = cols.length
760
793
  converted_rec = {}
761
- cols.each do |fieldnum, type_proc, fieldsym|
794
+ while fieldnum < nfields
795
+ type_proc, fieldsym = cols[fieldnum]
762
796
  value = res.getvalue(recnum, fieldnum)
763
797
  converted_rec[fieldsym] = (value && type_proc) ? type_proc.call(value) : value
798
+ fieldnum += 1
764
799
  end
765
800
  yield converted_rec
801
+ recnum += 1
766
802
  end
767
803
  end
768
804
  end
@@ -109,12 +109,6 @@ module Sequel
109
109
  complex_expression_sql_append(sql, :LIKE, args)
110
110
  when :'NOT ILIKE'
111
111
  complex_expression_sql_append(sql, :'NOT LIKE', args)
112
- when :LIKE, :'NOT LIKE'
113
- sql << '('
114
- literal_append(sql, args[0])
115
- sql << ' ' << op.to_s << ' '
116
- literal_append(sql, args[1])
117
- sql << ')'
118
112
  when :'!='
119
113
  sql << '('
120
114
  literal_append(sql, args[0])
@@ -177,6 +171,12 @@ module Sequel
177
171
  clone(:into => table)
178
172
  end
179
173
 
174
+ # Access uses [] for quoting identifiers, and can't handle
175
+ # ] inside identifiers.
176
+ def quoted_identifier_append(sql, v)
177
+ sql << '[' << v.to_s << ']'
178
+ end
179
+
180
180
  # Access does not support derived column lists.
181
181
  def supports_derived_column_lists?
182
182
  false
@@ -240,6 +240,16 @@ module Sequel
240
240
  end
241
241
  end
242
242
 
243
+ # Access does not natively support NULLS FIRST/LAST.
244
+ def requires_emulating_nulls_first?
245
+ true
246
+ end
247
+
248
+ # Access doesn't support ESCAPE for LIKE.
249
+ def requires_like_escape?
250
+ false
251
+ end
252
+
243
253
  # Access requires parentheses when joining more than one table
244
254
  def select_from_sql(sql)
245
255
  if f = @opts[:from]
@@ -275,12 +285,6 @@ module Sequel
275
285
  literal_append(sql, l)
276
286
  end
277
287
  end
278
-
279
- # Access uses [] for quoting identifiers, and can't handle
280
- # ] inside identifiers.
281
- def quoted_identifier_append(sql, v)
282
- sql << '[' << v.to_s << ']'
283
- end
284
288
  end
285
289
  end
286
290
  end
@@ -418,6 +418,11 @@ module Sequel
418
418
  false
419
419
  end
420
420
 
421
+ # At least some versions of DB do not support NULLS FIRST/LAST.
422
+ def requires_emulating_nulls_first?
423
+ true
424
+ end
425
+
421
426
  # Modify the sql to limit the number of rows returned.
422
427
  # Uses :offset_strategy Database option to determine how to format the
423
428
  # limit and offset.
@@ -40,6 +40,12 @@ module Sequel
40
40
  # :numrows :: The number of rows affected by the stored procedure
41
41
  # output params :: Values for any output paramters, using the name given for the output parameter
42
42
  #
43
+ # Because Sequel datasets only support a single result set per query, and retrieving
44
+ # the result code and number of rows requires a query, this does not support
45
+ # stored procedures which also return result sets. To handle such stored procedures,
46
+ # you should drop down to the connection/driver level by using Sequel::Database#synchronize
47
+ # to get access to the underlying connection object.
48
+ #
43
49
  # Examples:
44
50
  #
45
51
  # DB.call_mssql_sproc(:SequelTest, {args: ['input arg', :output]})
@@ -273,7 +279,7 @@ module Sequel
273
279
  end
274
280
  end
275
281
  sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
276
- 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
277
283
  sqls
278
284
  when :set_column_null
279
285
  sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
@@ -284,7 +290,9 @@ module Sequel
284
290
  end
285
291
  "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
286
292
  when :set_column_default
287
- "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])}"
288
296
  else
289
297
  super(table, op)
290
298
  end
@@ -421,20 +429,19 @@ module Sequel
421
429
  m = output_identifier_meth(opts[:dataset])
422
430
  m2 = input_identifier_meth(opts[:dataset])
423
431
  tn = m2.call(table_name.to_s)
424
- table_id = get(Sequel.function(:object_id, tn))
425
432
  info_sch_sch = opts[:information_schema_schema]
426
433
  inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel[s]}
427
- sys_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, Sequel.qualify(Sequel.lit(''), s)) : Sequel[s]}
434
+ table_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:objects])).where(:name => tn).select_map(:object_id).first
428
435
 
429
- identity_cols = metadata_dataset.from(Sequel.lit('[sys].[columns]')).
436
+ identity_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:columns])).
430
437
  where(:object_id=>table_id, :is_identity=>true).
431
438
  select_map(:name)
432
439
 
433
- pk_index_id = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexes'))).
440
+ pk_index_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexes])).
434
441
  where(:id=>table_id, :indid=>1..254){{(status & 2048)=>2048}}.
435
442
  get(:indid)
436
- pk_cols = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexkeys')).as(:sik)).
437
- join(sys_qual.call(Sequel.lit('syscolumns')).as(:sc), :id=>:id, :colid=>:colid).
443
+ pk_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexkeys]).as(:sik)).
444
+ join(inf_sch_qual.call(Sequel[:sys][:syscolumns]).as(:sc), :id=>:id, :colid=>:colid).
438
445
  where{{sik[:id]=>table_id, sik[:indid]=>pk_index_id}}.
439
446
  select_order_map{sc[:name]}
440
447
 
@@ -652,11 +659,11 @@ module Sequel
652
659
  # case by default, and that also adds a default order, so it's better to just
653
660
  # avoid the subquery.
654
661
  def select_sql
655
- if @opts[:offset] && !@opts[:order] && is_2012_or_later?
656
- order(1).select_sql
657
- else
658
- super
662
+ if @opts[:offset]
663
+ raise(Error, "Using with_ties is not supported with an offset on Microsoft SQL Server") if @opts[:limit_with_ties]
664
+ return order(1).select_sql if is_2012_or_later? && !@opts[:order]
659
665
  end
666
+ super
660
667
  end
661
668
 
662
669
  # The version of the database server.
@@ -748,6 +755,12 @@ module Sequel
748
755
  false
749
756
  end
750
757
 
758
+ # Use WITH TIES when limiting the result set to also include additional
759
+ # rows matching the last row.
760
+ def with_ties
761
+ clone(:limit_with_ties=>true)
762
+ end
763
+
751
764
  protected
752
765
 
753
766
  # If returned primary keys are requested, use OUTPUT unless already set on the
@@ -759,19 +772,15 @@ module Sequel
759
772
  output(nil, [SQL::QualifiedIdentifier.new(:inserted, first_primary_key)])._import(columns, values, opts)
760
773
  elsif @opts[:output]
761
774
  statements = multi_insert_sql(columns, values)
775
+ ds = naked
762
776
  @db.transaction(opts.merge(:server=>@opts[:server])) do
763
- statements.map{|st| with_sql(st)}
777
+ statements.map{|st| ds.with_sql(st)}
764
778
  end.first.map{|v| v.length == 1 ? v.values.first : v}
765
779
  else
766
780
  super
767
781
  end
768
782
  end
769
783
 
770
- # MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
771
- def aggregate_dataset
772
- (options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
773
- end
774
-
775
784
  # If the dataset using a order without a limit or offset or custom SQL,
776
785
  # remove the order. Compounds on Microsoft SQL Server have undefined
777
786
  # order unless the result is specifically ordered. Applying the current
@@ -791,6 +800,11 @@ module Sequel
791
800
 
792
801
  private
793
802
 
803
+ # MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
804
+ def aggregate_dataset
805
+ (options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
806
+ end
807
+
794
808
  # Allow update and delete for unordered, limited datasets only.
795
809
  def check_not_limited!(type)
796
810
  return if @opts[:skip_limit_check] && type != :truncate
@@ -951,6 +965,10 @@ module Sequel
951
965
  sql << " TOP "
952
966
  literal_append(sql, l)
953
967
  end
968
+
969
+ if @opts[:limit_with_ties]
970
+ sql << " WITH TIES"
971
+ end
954
972
  end
955
973
 
956
974
  def update_limit_sql(sql)
@@ -1046,6 +1064,11 @@ module Sequel
1046
1064
  end
1047
1065
  end
1048
1066
 
1067
+ # MSSQL does not natively support NULLS FIRST/LAST.
1068
+ def requires_emulating_nulls_first?
1069
+ true
1070
+ end
1071
+
1049
1072
  # MSSQL supports 100-nsec precision for time columns, but ruby by
1050
1073
  # default only supports usec precision.
1051
1074
  def sqltime_precision
@@ -19,7 +19,7 @@ module Sequel
19
19
  include Sequel::Database::SplitAlterTable
20
20
 
21
21
  CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}.freeze
22
- COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze
22
+ COLUMN_DEFINITION_ORDER = [:generated, :collate, :null, :default, :unique, :primary_key, :auto_increment, :references].freeze
23
23
 
24
24
  # Set the default charset used for CREATE TABLE. You can pass the
25
25
  # :charset option to create_table to override this setting.
@@ -137,6 +137,11 @@ module Sequel
137
137
  true
138
138
  end
139
139
 
140
+ # Generated columns are supported in MariaDB 5.2.0+ and MySQL 5.7.6+.
141
+ def supports_generated_columns?
142
+ server_version >= (mariadb? ? 50200 : 50706)
143
+ end
144
+
140
145
  # MySQL 5+ supports prepared transactions (two-phase commit) using XA
141
146
  def supports_prepared_transactions?
142
147
  server_version >= 50000
@@ -227,7 +232,18 @@ module Sequel
227
232
  alias alter_table_rename_column_sql alter_table_change_column_sql
228
233
  alias alter_table_set_column_type_sql alter_table_change_column_sql
229
234
  alias alter_table_set_column_null_sql alter_table_change_column_sql
230
- alias alter_table_set_column_default_sql alter_table_change_column_sql
235
+
236
+ def alter_table_set_column_default_sql(table, op)
237
+ return super unless op[:default].nil?
238
+
239
+ opts = schema(table).find{|x| x[0] == op[:name]}
240
+
241
+ if opts && opts[1][:allow_null] == false
242
+ "ALTER COLUMN #{quote_identifier(op[:name])} DROP DEFAULT"
243
+ else
244
+ super
245
+ end
246
+ end
231
247
 
232
248
  def alter_table_add_constraint_sql(table, op)
233
249
  if op[:type] == :foreign_key
@@ -331,6 +347,23 @@ module Sequel
331
347
  end
332
348
  end
333
349
 
350
+ # Add generation clause SQL fragment to column creation SQL.
351
+ def column_definition_generated_sql(sql, column)
352
+ if (generated_expression = column[:generated_always_as])
353
+ sql << " GENERATED ALWAYS AS (#{literal(generated_expression)})"
354
+ case (type = column[:generated_type])
355
+ when nil
356
+ # none, database default
357
+ when :virtual
358
+ sql << " VIRTUAL"
359
+ when :stored
360
+ sql << (mariadb? ? " PERSISTENT" : " STORED")
361
+ else
362
+ raise Error, "unsupported :generated_type option: #{type.inspect}"
363
+ end
364
+ end
365
+ end
366
+
334
367
  def column_definition_order
335
368
  COLUMN_DEFINITION_ORDER
336
369
  end
@@ -408,7 +441,7 @@ module Sequel
408
441
  /cannot be null/ => NotNullConstraintViolation,
409
442
  /Deadlock found when trying to get lock; try restarting transaction/ => SerializationFailure,
410
443
  /CONSTRAINT .+ failed for/ => CheckConstraintViolation,
411
- /\AStatement aborted because lock\(s\) could not be acquired immediately and NOWAIT is set\./ => DatabaseLockTimeout,
444
+ /\A(Statement aborted because lock\(s\) could not be acquired immediately and NOWAIT is set\.|Lock wait timeout exceeded; try restarting transaction)/ => DatabaseLockTimeout,
412
445
  }.freeze
413
446
  def database_error_regexps
414
447
  DATABASE_ERROR_REGEXPS
@@ -473,7 +506,11 @@ module Sequel
473
506
  metadata_dataset.with_sql("DESCRIBE ?", table).map do |row|
474
507
  extra = row.delete(:Extra)
475
508
  if row[:primary_key] = row.delete(:Key) == 'PRI'
476
- row[:auto_increment] = !!(extra.to_s =~ /auto_increment/io)
509
+ row[:auto_increment] = !!(extra.to_s =~ /auto_increment/i)
510
+ end
511
+ if supports_generated_columns?
512
+ # Extra field contains VIRTUAL or PERSISTENT for generated columns
513
+ row[:generated] = !!(extra.to_s =~ /VIRTUAL|STORED|PERSISTENT/i)
477
514
  end
478
515
  row[:allow_null] = row.delete(:Null) == 'YES'
479
516
  row[:default] = row.delete(:Default)
@@ -565,7 +602,7 @@ module Sequel
565
602
 
566
603
  Dataset.def_sql_method(self, :delete, %w'with delete from where order limit')
567
604
  Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update')
568
- Dataset.def_sql_method(self, :select, %w'with select distinct calc_found_rows columns from join where group having compounds order limit lock')
605
+ Dataset.def_sql_method(self, :select, %w'with select distinct calc_found_rows columns from join where group having window compounds order limit lock')
569
606
  Dataset.def_sql_method(self, :update, %w'with update ignore table set where order limit')
570
607
 
571
608
  include Sequel::Dataset::Replace
@@ -654,7 +691,7 @@ module Sequel
654
691
  end
655
692
 
656
693
  # Return the results of an EXPLAIN query as a string. Options:
657
- # :extended :: Use EXPLAIN EXPTENDED instead of EXPLAIN if true.
694
+ # :extended :: Use EXPLAIN EXTENDED instead of EXPLAIN if true.
658
695
  def explain(opts=OPTS)
659
696
  # Load the PrettyTable class, needed for explain output
660
697
  Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
@@ -680,15 +717,6 @@ module Sequel
680
717
  SQL::PlaceholderLiteralString.new((opts[:boolean] ? MATCH_AGAINST_BOOLEAN : MATCH_AGAINST), [Array(cols), terms])
681
718
  end
682
719
 
683
- # Transforms :straight to STRAIGHT_JOIN.
684
- def join_type_sql(join_type)
685
- if join_type == :straight
686
- 'STRAIGHT_JOIN'
687
- else
688
- super
689
- end
690
- end
691
-
692
720
  # Sets up the insert methods to use INSERT IGNORE.
693
721
  # Useful if you have a unique key and want to just skip
694
722
  # inserting rows that violate the unique key restriction.
@@ -767,9 +795,9 @@ module Sequel
767
795
  true
768
796
  end
769
797
 
770
- # MySQL does not support INTERSECT or EXCEPT
798
+ # MariaDB 10.3+ supports INTERSECT or EXCEPT
771
799
  def supports_intersect_except?
772
- false
800
+ db.mariadb? && db.server_version >= 100300
773
801
  end
774
802
 
775
803
  # MySQL does not support limits in correlated subqueries (or any subqueries that use IN).
@@ -782,9 +810,9 @@ module Sequel
782
810
  true
783
811
  end
784
812
 
785
- # MySQL 8+ supports NOWAIT.
813
+ # MySQL 8+ and MariaDB 10.3+ support NOWAIT.
786
814
  def supports_nowait?
787
- !db.mariadb? && db.server_version >= 80000
815
+ db.server_version >= (db.mariadb? ? 100300 : 80000)
788
816
  end
789
817
 
790
818
  # MySQL's DISTINCT ON emulation using GROUP BY does not respect the
@@ -809,6 +837,11 @@ module Sequel
809
837
  db.supports_timestamp_usecs?
810
838
  end
811
839
 
840
+ # MySQL 8+ supports WINDOW clause.
841
+ def supports_window_clause?
842
+ !db.mariadb? && db.server_version >= 80000
843
+ end
844
+
812
845
  # MariaDB 10.2+ and MySQL 8+ support window functions
813
846
  def supports_window_functions?
814
847
  db.server_version >= (db.mariadb? ? 100200 : 80000)
@@ -914,6 +947,15 @@ module Sequel
914
947
  end
915
948
  end
916
949
 
950
+ # Transforms :straight to STRAIGHT_JOIN.
951
+ def join_type_sql(join_type)
952
+ if join_type == :straight
953
+ 'STRAIGHT_JOIN'
954
+ else
955
+ super
956
+ end
957
+ end
958
+
917
959
  # MySQL allows a LIMIT in DELETE and UPDATE statements.
918
960
  def limit_sql(sql)
919
961
  if l = @opts[:limit]
@@ -966,6 +1008,11 @@ module Sequel
966
1008
  super || key == :insert_ignore || key == :update_ignore || key == :on_duplicate_key_update
967
1009
  end
968
1010
 
1011
+ # MySQL does not natively support NULLS FIRST/LAST.
1012
+ def requires_emulating_nulls_first?
1013
+ true
1014
+ end
1015
+
969
1016
  def select_only_offset_sql(sql)
970
1017
  sql << " LIMIT "
971
1018
  literal_append(sql, @opts[:offset])