sequel 5.20.0 → 5.49.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 (511) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +398 -1922
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/doc/advanced_associations.rdoc +4 -4
  6. data/doc/association_basics.rdoc +80 -16
  7. data/doc/cheat_sheet.rdoc +6 -5
  8. data/doc/code_order.rdoc +10 -12
  9. data/doc/dataset_filtering.rdoc +17 -2
  10. data/doc/fork_safety.rdoc +84 -0
  11. data/doc/migration.rdoc +11 -5
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +10 -2
  15. data/doc/postgresql.rdoc +82 -3
  16. data/doc/querying.rdoc +4 -4
  17. data/doc/release_notes/5.21.0.txt +87 -0
  18. data/doc/release_notes/5.22.0.txt +48 -0
  19. data/doc/release_notes/5.23.0.txt +56 -0
  20. data/doc/release_notes/5.24.0.txt +56 -0
  21. data/doc/release_notes/5.25.0.txt +32 -0
  22. data/doc/release_notes/5.26.0.txt +35 -0
  23. data/doc/release_notes/5.27.0.txt +21 -0
  24. data/doc/release_notes/5.28.0.txt +16 -0
  25. data/doc/release_notes/5.29.0.txt +22 -0
  26. data/doc/release_notes/5.30.0.txt +20 -0
  27. data/doc/release_notes/5.31.0.txt +148 -0
  28. data/doc/release_notes/5.32.0.txt +46 -0
  29. data/doc/release_notes/5.33.0.txt +24 -0
  30. data/doc/release_notes/5.34.0.txt +40 -0
  31. data/doc/release_notes/5.35.0.txt +56 -0
  32. data/doc/release_notes/5.36.0.txt +60 -0
  33. data/doc/release_notes/5.37.0.txt +30 -0
  34. data/doc/release_notes/5.38.0.txt +28 -0
  35. data/doc/release_notes/5.39.0.txt +19 -0
  36. data/doc/release_notes/5.40.0.txt +40 -0
  37. data/doc/release_notes/5.41.0.txt +25 -0
  38. data/doc/release_notes/5.42.0.txt +136 -0
  39. data/doc/release_notes/5.43.0.txt +98 -0
  40. data/doc/release_notes/5.44.0.txt +32 -0
  41. data/doc/release_notes/5.45.0.txt +34 -0
  42. data/doc/release_notes/5.46.0.txt +87 -0
  43. data/doc/release_notes/5.47.0.txt +59 -0
  44. data/doc/release_notes/5.48.0.txt +14 -0
  45. data/doc/release_notes/5.49.0.txt +59 -0
  46. data/doc/sharding.rdoc +2 -0
  47. data/doc/sql.rdoc +13 -1
  48. data/doc/testing.rdoc +20 -7
  49. data/doc/transactions.rdoc +0 -8
  50. data/doc/validations.rdoc +1 -1
  51. data/doc/virtual_rows.rdoc +1 -1
  52. data/lib/sequel/adapters/ado/access.rb +1 -1
  53. data/lib/sequel/adapters/ado.rb +43 -35
  54. data/lib/sequel/adapters/ibmdb.rb +2 -2
  55. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  56. data/lib/sequel/adapters/jdbc/postgresql.rb +11 -17
  57. data/lib/sequel/adapters/jdbc/sqlite.rb +29 -0
  58. data/lib/sequel/adapters/jdbc.rb +24 -6
  59. data/lib/sequel/adapters/mysql.rb +1 -1
  60. data/lib/sequel/adapters/mysql2.rb +2 -3
  61. data/lib/sequel/adapters/odbc.rb +8 -6
  62. data/lib/sequel/adapters/oracle.rb +5 -4
  63. data/lib/sequel/adapters/postgres.rb +15 -9
  64. data/lib/sequel/adapters/shared/access.rb +6 -6
  65. data/lib/sequel/adapters/shared/mssql.rb +66 -21
  66. data/lib/sequel/adapters/shared/mysql.rb +27 -10
  67. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  68. data/lib/sequel/adapters/shared/postgres.rb +271 -32
  69. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  70. data/lib/sequel/adapters/shared/sqlite.rb +161 -19
  71. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  72. data/lib/sequel/adapters/sqlite.rb +1 -1
  73. data/lib/sequel/adapters/tinytds.rb +15 -2
  74. data/lib/sequel/adapters/utils/mysql_mysql2.rb +4 -1
  75. data/lib/sequel/ast_transformer.rb +6 -0
  76. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  77. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  78. data/lib/sequel/connection_pool/single.rb +1 -1
  79. data/lib/sequel/connection_pool/threaded.rb +2 -2
  80. data/lib/sequel/core.rb +333 -319
  81. data/lib/sequel/database/connecting.rb +3 -4
  82. data/lib/sequel/database/logging.rb +7 -1
  83. data/lib/sequel/database/misc.rb +31 -12
  84. data/lib/sequel/database/query.rb +3 -1
  85. data/lib/sequel/database/schema_generator.rb +53 -51
  86. data/lib/sequel/database/schema_methods.rb +38 -23
  87. data/lib/sequel/database/transactions.rb +17 -18
  88. data/lib/sequel/dataset/actions.rb +14 -9
  89. data/lib/sequel/dataset/features.rb +16 -0
  90. data/lib/sequel/dataset/misc.rb +2 -2
  91. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  92. data/lib/sequel/dataset/prepared_statements.rb +2 -0
  93. data/lib/sequel/dataset/query.rb +26 -9
  94. data/lib/sequel/dataset/sql.rb +76 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/deprecated.rb +3 -1
  97. data/lib/sequel/exceptions.rb +2 -0
  98. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  99. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  100. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  101. data/lib/sequel/extensions/blank.rb +8 -0
  102. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  103. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  104. data/lib/sequel/extensions/connection_validator.rb +2 -2
  105. data/lib/sequel/extensions/core_refinements.rb +2 -0
  106. data/lib/sequel/extensions/date_arithmetic.rb +36 -24
  107. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
  108. data/lib/sequel/extensions/eval_inspect.rb +2 -0
  109. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  110. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  111. data/lib/sequel/extensions/index_caching.rb +9 -7
  112. data/lib/sequel/extensions/inflector.rb +9 -1
  113. data/lib/sequel/extensions/integer64.rb +2 -0
  114. data/lib/sequel/extensions/migration.rb +11 -3
  115. data/lib/sequel/extensions/named_timezones.rb +56 -8
  116. data/lib/sequel/extensions/pagination.rb +1 -1
  117. data/lib/sequel/extensions/pg_array.rb +5 -0
  118. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  119. data/lib/sequel/extensions/pg_enum.rb +11 -3
  120. data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
  121. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  122. data/lib/sequel/extensions/pg_hstore_ops.rb +54 -2
  123. data/lib/sequel/extensions/pg_inet.rb +15 -5
  124. data/lib/sequel/extensions/pg_interval.rb +36 -8
  125. data/lib/sequel/extensions/pg_json.rb +387 -123
  126. data/lib/sequel/extensions/pg_json_ops.rb +238 -0
  127. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  128. data/lib/sequel/extensions/pg_range.rb +17 -9
  129. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  130. data/lib/sequel/extensions/pg_row.rb +4 -2
  131. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  132. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  133. data/lib/sequel/extensions/query.rb +3 -0
  134. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  135. data/lib/sequel/extensions/s.rb +2 -0
  136. data/lib/sequel/extensions/schema_dumper.rb +24 -7
  137. data/lib/sequel/extensions/server_block.rb +18 -7
  138. data/lib/sequel/extensions/sql_comments.rb +2 -2
  139. data/lib/sequel/extensions/string_agg.rb +1 -1
  140. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  141. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  142. data/lib/sequel/extensions/to_dot.rb +9 -3
  143. data/lib/sequel/model/associations.rb +356 -117
  144. data/lib/sequel/model/base.rb +107 -68
  145. data/lib/sequel/model/errors.rb +10 -1
  146. data/lib/sequel/model/inflections.rb +1 -1
  147. data/lib/sequel/model/plugins.rb +9 -3
  148. data/lib/sequel/model.rb +3 -1
  149. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  150. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  151. data/lib/sequel/plugins/association_pks.rb +60 -18
  152. data/lib/sequel/plugins/association_proxies.rb +8 -2
  153. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  154. data/lib/sequel/plugins/auto_validations.rb +39 -5
  155. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  156. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  157. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  158. data/lib/sequel/plugins/caching.rb +3 -0
  159. data/lib/sequel/plugins/class_table_inheritance.rb +33 -28
  160. data/lib/sequel/plugins/column_encryption.rb +728 -0
  161. data/lib/sequel/plugins/composition.rb +7 -2
  162. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  163. data/lib/sequel/plugins/constraint_validations.rb +2 -1
  164. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  165. data/lib/sequel/plugins/dataset_associations.rb +4 -1
  166. data/lib/sequel/plugins/dirty.rb +60 -22
  167. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  168. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  169. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  170. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  171. data/lib/sequel/plugins/json_serializer.rb +57 -35
  172. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  173. data/lib/sequel/plugins/many_through_many.rb +108 -9
  174. data/lib/sequel/plugins/nested_attributes.rb +15 -3
  175. data/lib/sequel/plugins/pg_array_associations.rb +58 -41
  176. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +91 -30
  177. data/lib/sequel/plugins/prepared_statements.rb +15 -12
  178. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  179. data/lib/sequel/plugins/rcte_tree.rb +43 -35
  180. data/lib/sequel/plugins/serialization.rb +8 -3
  181. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  182. data/lib/sequel/plugins/sharding.rb +11 -5
  183. data/lib/sequel/plugins/single_table_inheritance.rb +22 -15
  184. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  185. data/lib/sequel/plugins/static_cache.rb +9 -4
  186. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  187. data/lib/sequel/plugins/string_stripper.rb +1 -1
  188. data/lib/sequel/plugins/subclasses.rb +2 -0
  189. data/lib/sequel/plugins/throw_failures.rb +1 -1
  190. data/lib/sequel/plugins/timestamps.rb +1 -1
  191. data/lib/sequel/plugins/tree.rb +9 -4
  192. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  193. data/lib/sequel/plugins/unused_associations.rb +521 -0
  194. data/lib/sequel/plugins/update_or_create.rb +1 -1
  195. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  196. data/lib/sequel/plugins/validation_helpers.rb +18 -11
  197. data/lib/sequel/plugins/xml_serializer.rb +1 -1
  198. data/lib/sequel/sql.rb +20 -5
  199. data/lib/sequel/timezones.rb +63 -17
  200. data/lib/sequel/version.rb +1 -1
  201. metadata +113 -381
  202. data/Rakefile +0 -151
  203. data/doc/release_notes/4.0.0.txt +0 -262
  204. data/doc/release_notes/4.1.0.txt +0 -85
  205. data/doc/release_notes/4.10.0.txt +0 -226
  206. data/doc/release_notes/4.11.0.txt +0 -147
  207. data/doc/release_notes/4.12.0.txt +0 -105
  208. data/doc/release_notes/4.13.0.txt +0 -169
  209. data/doc/release_notes/4.14.0.txt +0 -68
  210. data/doc/release_notes/4.15.0.txt +0 -56
  211. data/doc/release_notes/4.16.0.txt +0 -36
  212. data/doc/release_notes/4.17.0.txt +0 -38
  213. data/doc/release_notes/4.18.0.txt +0 -36
  214. data/doc/release_notes/4.19.0.txt +0 -45
  215. data/doc/release_notes/4.2.0.txt +0 -129
  216. data/doc/release_notes/4.20.0.txt +0 -79
  217. data/doc/release_notes/4.21.0.txt +0 -94
  218. data/doc/release_notes/4.22.0.txt +0 -72
  219. data/doc/release_notes/4.23.0.txt +0 -65
  220. data/doc/release_notes/4.24.0.txt +0 -99
  221. data/doc/release_notes/4.25.0.txt +0 -181
  222. data/doc/release_notes/4.26.0.txt +0 -44
  223. data/doc/release_notes/4.27.0.txt +0 -78
  224. data/doc/release_notes/4.28.0.txt +0 -57
  225. data/doc/release_notes/4.29.0.txt +0 -41
  226. data/doc/release_notes/4.3.0.txt +0 -40
  227. data/doc/release_notes/4.30.0.txt +0 -37
  228. data/doc/release_notes/4.31.0.txt +0 -57
  229. data/doc/release_notes/4.32.0.txt +0 -132
  230. data/doc/release_notes/4.33.0.txt +0 -88
  231. data/doc/release_notes/4.34.0.txt +0 -86
  232. data/doc/release_notes/4.35.0.txt +0 -130
  233. data/doc/release_notes/4.36.0.txt +0 -116
  234. data/doc/release_notes/4.37.0.txt +0 -50
  235. data/doc/release_notes/4.38.0.txt +0 -67
  236. data/doc/release_notes/4.39.0.txt +0 -127
  237. data/doc/release_notes/4.4.0.txt +0 -92
  238. data/doc/release_notes/4.40.0.txt +0 -179
  239. data/doc/release_notes/4.41.0.txt +0 -77
  240. data/doc/release_notes/4.42.0.txt +0 -221
  241. data/doc/release_notes/4.43.0.txt +0 -87
  242. data/doc/release_notes/4.44.0.txt +0 -125
  243. data/doc/release_notes/4.45.0.txt +0 -370
  244. data/doc/release_notes/4.46.0.txt +0 -404
  245. data/doc/release_notes/4.47.0.txt +0 -56
  246. data/doc/release_notes/4.48.0.txt +0 -293
  247. data/doc/release_notes/4.49.0.txt +0 -222
  248. data/doc/release_notes/4.5.0.txt +0 -34
  249. data/doc/release_notes/4.6.0.txt +0 -30
  250. data/doc/release_notes/4.7.0.txt +0 -103
  251. data/doc/release_notes/4.8.0.txt +0 -175
  252. data/doc/release_notes/4.9.0.txt +0 -190
  253. data/spec/adapter_spec.rb +0 -4
  254. data/spec/adapters/db2_spec.rb +0 -170
  255. data/spec/adapters/mssql_spec.rb +0 -804
  256. data/spec/adapters/mysql_spec.rb +0 -1065
  257. data/spec/adapters/oracle_spec.rb +0 -371
  258. data/spec/adapters/postgres_spec.rb +0 -4125
  259. data/spec/adapters/spec_helper.rb +0 -44
  260. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  261. data/spec/adapters/sqlite_spec.rb +0 -652
  262. data/spec/bin_spec.rb +0 -278
  263. data/spec/core/connection_pool_spec.rb +0 -1250
  264. data/spec/core/database_spec.rb +0 -2865
  265. data/spec/core/dataset_spec.rb +0 -5515
  266. data/spec/core/deprecated_spec.rb +0 -70
  267. data/spec/core/expression_filters_spec.rb +0 -1455
  268. data/spec/core/mock_adapter_spec.rb +0 -722
  269. data/spec/core/object_graph_spec.rb +0 -336
  270. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  271. data/spec/core/schema_generator_spec.rb +0 -214
  272. data/spec/core/schema_spec.rb +0 -1826
  273. data/spec/core/spec_helper.rb +0 -24
  274. data/spec/core/version_spec.rb +0 -14
  275. data/spec/core_extensions_spec.rb +0 -763
  276. data/spec/core_model_spec.rb +0 -2
  277. data/spec/core_spec.rb +0 -1
  278. data/spec/deprecation_helper.rb +0 -30
  279. data/spec/extensions/accessed_columns_spec.rb +0 -51
  280. data/spec/extensions/active_model_spec.rb +0 -99
  281. data/spec/extensions/after_initialize_spec.rb +0 -28
  282. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  283. data/spec/extensions/association_dependencies_spec.rb +0 -125
  284. data/spec/extensions/association_pks_spec.rb +0 -423
  285. data/spec/extensions/association_proxies_spec.rb +0 -100
  286. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  287. data/spec/extensions/auto_validations_spec.rb +0 -229
  288. data/spec/extensions/blacklist_security_spec.rb +0 -95
  289. data/spec/extensions/blank_spec.rb +0 -69
  290. data/spec/extensions/boolean_readers_spec.rb +0 -93
  291. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  292. data/spec/extensions/caching_spec.rb +0 -273
  293. data/spec/extensions/caller_logging_spec.rb +0 -52
  294. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  295. data/spec/extensions/column_conflicts_spec.rb +0 -75
  296. data/spec/extensions/column_select_spec.rb +0 -129
  297. data/spec/extensions/columns_introspection_spec.rb +0 -90
  298. data/spec/extensions/columns_updated_spec.rb +0 -35
  299. data/spec/extensions/composition_spec.rb +0 -248
  300. data/spec/extensions/connection_expiration_spec.rb +0 -151
  301. data/spec/extensions/connection_validator_spec.rb +0 -144
  302. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  303. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  304. data/spec/extensions/constraint_validations_spec.rb +0 -439
  305. data/spec/extensions/core_refinements_spec.rb +0 -528
  306. data/spec/extensions/csv_serializer_spec.rb +0 -183
  307. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  308. data/spec/extensions/dataset_associations_spec.rb +0 -365
  309. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  310. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  311. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  312. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  313. data/spec/extensions/defaults_setter_spec.rb +0 -150
  314. data/spec/extensions/delay_add_association_spec.rb +0 -73
  315. data/spec/extensions/dirty_spec.rb +0 -189
  316. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  317. data/spec/extensions/eager_each_spec.rb +0 -62
  318. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  319. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  320. data/spec/extensions/error_splitter_spec.rb +0 -18
  321. data/spec/extensions/error_sql_spec.rb +0 -20
  322. data/spec/extensions/escaped_like_spec.rb +0 -40
  323. data/spec/extensions/eval_inspect_spec.rb +0 -81
  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 -402
  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 -291
  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 -864
  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 -111
  348. data/spec/extensions/nested_attributes_spec.rb +0 -767
  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 -172
  356. data/spec/extensions/pg_enum_spec.rb +0 -118
  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 -519
  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 -177
  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 -870
  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 -63
  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 -471
  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 -402
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/throw_failures_spec.rb +0 -74
  411. data/spec/extensions/timestamps_spec.rb +0 -209
  412. data/spec/extensions/to_dot_spec.rb +0 -153
  413. data/spec/extensions/touch_spec.rb +0 -226
  414. data/spec/extensions/tree_spec.rb +0 -334
  415. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  416. data/spec/extensions/unlimited_update_spec.rb +0 -21
  417. data/spec/extensions/update_or_create_spec.rb +0 -83
  418. data/spec/extensions/update_primary_key_spec.rb +0 -105
  419. data/spec/extensions/update_refresh_spec.rb +0 -59
  420. data/spec/extensions/uuid_spec.rb +0 -101
  421. data/spec/extensions/validate_associated_spec.rb +0 -52
  422. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  423. data/spec/extensions/validation_contexts_spec.rb +0 -31
  424. data/spec/extensions/validation_helpers_spec.rb +0 -525
  425. data/spec/extensions/whitelist_security_spec.rb +0 -157
  426. data/spec/extensions/xml_serializer_spec.rb +0 -213
  427. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  428. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  429. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  431. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  432. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  433. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  434. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  436. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  437. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  438. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  439. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  440. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  441. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  443. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  444. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  446. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  447. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  448. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  449. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  450. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  451. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  452. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  453. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  457. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  458. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  459. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  460. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  461. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  462. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  466. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  468. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  469. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  471. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  473. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  474. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  475. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  476. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  478. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  479. data/spec/guards_helper.rb +0 -59
  480. data/spec/integration/associations_test.rb +0 -2597
  481. data/spec/integration/database_test.rb +0 -113
  482. data/spec/integration/dataset_test.rb +0 -1981
  483. data/spec/integration/eager_loader_test.rb +0 -687
  484. data/spec/integration/migrator_test.rb +0 -262
  485. data/spec/integration/model_test.rb +0 -203
  486. data/spec/integration/plugin_test.rb +0 -2396
  487. data/spec/integration/prepared_statement_test.rb +0 -405
  488. data/spec/integration/schema_test.rb +0 -889
  489. data/spec/integration/spec_helper.rb +0 -65
  490. data/spec/integration/timezone_test.rb +0 -86
  491. data/spec/integration/transaction_test.rb +0 -603
  492. data/spec/integration/type_test.rb +0 -127
  493. data/spec/model/association_reflection_spec.rb +0 -803
  494. data/spec/model/associations_spec.rb +0 -4738
  495. data/spec/model/base_spec.rb +0 -875
  496. data/spec/model/class_dataset_methods_spec.rb +0 -146
  497. data/spec/model/dataset_methods_spec.rb +0 -198
  498. data/spec/model/eager_loading_spec.rb +0 -2377
  499. data/spec/model/hooks_spec.rb +0 -370
  500. data/spec/model/inflector_spec.rb +0 -26
  501. data/spec/model/model_spec.rb +0 -956
  502. data/spec/model/plugins_spec.rb +0 -429
  503. data/spec/model/record_spec.rb +0 -2118
  504. data/spec/model/spec_helper.rb +0 -46
  505. data/spec/model/validations_spec.rb +0 -220
  506. data/spec/model_no_assoc_spec.rb +0 -1
  507. data/spec/model_spec.rb +0 -1
  508. data/spec/plugin_spec.rb +0 -1
  509. data/spec/sequel_coverage.rb +0 -15
  510. data/spec/sequel_warning.rb +0 -4
  511. data/spec/spec_config.rb +0 -12
@@ -97,13 +97,17 @@ module Sequel
97
97
  # Add an exclusion constraint when creating the table. Elements should be
98
98
  # an array of 2 element arrays, with the first element being the column or
99
99
  # expression the exclusion constraint is applied to, and the second element
100
- # being the operator to use for the column/expression to check for exclusion.
101
- #
102
- # Example:
100
+ # being the operator to use for the column/expression to check for exclusion:
103
101
  #
104
102
  # exclude([[:col1, '&&'], [:col2, '=']])
105
103
  # # EXCLUDE USING gist (col1 WITH &&, col2 WITH =)
106
104
  #
105
+ # To use a custom operator class, you need to use Sequel.lit with the expression
106
+ # and operator class:
107
+ #
108
+ # exclude([[Sequel.lit('col1 inet_ops'), '&&'], [:col2, '=']])
109
+ # # EXCLUDE USING gist (col1 inet_ops WITH &&, col2 WITH =)
110
+ #
107
111
  # Options supported:
108
112
  #
109
113
  # :name :: Name the constraint with the given name (useful if you may
@@ -130,6 +134,96 @@ module Sequel
130
134
  end
131
135
  end
132
136
 
137
+ # Generator used for creating tables that are partitions of other tables.
138
+ class CreatePartitionOfTableGenerator
139
+ MINVALUE = Sequel.lit('MINVALUE').freeze
140
+ MAXVALUE = Sequel.lit('MAXVALUE').freeze
141
+
142
+ def initialize(&block)
143
+ instance_exec(&block)
144
+ end
145
+
146
+ # The minimum value of the data type used in range partitions, useful
147
+ # as an argument to #from.
148
+ def minvalue
149
+ MINVALUE
150
+ end
151
+
152
+ # The minimum value of the data type used in range partitions, useful
153
+ # as an argument to #to.
154
+ def maxvalue
155
+ MAXVALUE
156
+ end
157
+
158
+ # Assumes range partitioning, sets the inclusive minimum value of the range for
159
+ # this partition.
160
+ def from(*v)
161
+ @from = v
162
+ end
163
+
164
+ # Assumes range partitioning, sets the exclusive maximum value of the range for
165
+ # this partition.
166
+ def to(*v)
167
+ @to = v
168
+ end
169
+
170
+ # Assumes list partitioning, sets the values to be included in this partition.
171
+ def values_in(*v)
172
+ @in = v
173
+ end
174
+
175
+ # Assumes hash partitioning, sets the modulus for this parition.
176
+ def modulus(v)
177
+ @modulus = v
178
+ end
179
+
180
+ # Assumes hash partitioning, sets the remainder for this parition.
181
+ def remainder(v)
182
+ @remainder = v
183
+ end
184
+
185
+ # Sets that this is a default partition, where values not in other partitions
186
+ # are stored.
187
+ def default
188
+ @default = true
189
+ end
190
+
191
+ # The from and to values of this partition for a range partition.
192
+ def range
193
+ [@from, @to]
194
+ end
195
+
196
+ # The values to include in this partition for a list partition.
197
+ def list
198
+ @in
199
+ end
200
+
201
+ # The modulus and remainder to use for this partition for a hash partition.
202
+ def hash_values
203
+ [@modulus, @remainder]
204
+ end
205
+
206
+ # Determine the appropriate partition type for this partition by which methods
207
+ # were called on it.
208
+ def partition_type
209
+ raise Error, "Unable to determine partition type, multiple different partitioning methods called" if [@from || @to, @list, @modulus || @remainder, @default].compact.length > 1
210
+
211
+ if @from || @to
212
+ raise Error, "must call both from and to when creating a partition of a table if calling either" unless @from && @to
213
+ :range
214
+ elsif @in
215
+ :list
216
+ elsif @modulus || @remainder
217
+ raise Error, "must call both modulus and remainder when creating a partition of a table if calling either" unless @modulus && @remainder
218
+ :hash
219
+ elsif @default
220
+ :default
221
+ else
222
+ raise Error, "unable to determine partition type, no partitioning methods called"
223
+ end
224
+ end
225
+ end
226
+
133
227
  # Error raised when Sequel determines a PostgreSQL exclusion constraint has been violated.
134
228
  class ExclusionConstraintViolation < Sequel::ConstraintViolation; end
135
229
 
@@ -147,10 +241,10 @@ module Sequel
147
241
  SELECT_CUSTOM_SEQUENCE_SQL = (<<-end_sql
148
242
  SELECT name.nspname AS "schema",
149
243
  CASE
150
- WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
151
- substr(split_part(def.adsrc, '''', 2),
152
- strpos(split_part(def.adsrc, '''', 2), '.')+1)
153
- ELSE split_part(def.adsrc, '''', 2)
244
+ WHEN split_part(pg_get_expr(def.adbin, attr.attrelid), '''', 2) ~ '.' THEN
245
+ substr(split_part(pg_get_expr(def.adbin, attr.attrelid), '''', 2),
246
+ strpos(split_part(pg_get_expr(def.adbin, attr.attrelid), '''', 2), '.')+1)
247
+ ELSE split_part(pg_get_expr(def.adbin, attr.attrelid), '''', 2)
154
248
  END AS "sequence"
155
249
  FROM pg_class t
156
250
  JOIN pg_namespace name ON (t.relnamespace = name.oid)
@@ -158,7 +252,7 @@ module Sequel
158
252
  JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
159
253
  JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
160
254
  WHERE cons.contype = 'p'
161
- AND def.adsrc ~* 'nextval'
255
+ AND pg_get_expr(def.adbin, attr.attrelid) ~* 'nextval'
162
256
  end_sql
163
257
  ).strip.gsub(/\s+/, ' ').freeze
164
258
 
@@ -355,6 +449,26 @@ module Sequel
355
449
  self << create_schema_sql(name, opts)
356
450
  end
357
451
 
452
+ # Support partitions of tables using the :partition_of option.
453
+ def create_table(name, options=OPTS, &block)
454
+ if options[:partition_of]
455
+ create_partition_of_table_from_generator(name, CreatePartitionOfTableGenerator.new(&block), options)
456
+ return
457
+ end
458
+
459
+ super
460
+ end
461
+
462
+ # Support partitions of tables using the :partition_of option.
463
+ def create_table?(name, options=OPTS, &block)
464
+ if options[:partition_of]
465
+ create_table(name, options.merge!(:if_not_exists=>true), &block)
466
+ return
467
+ end
468
+
469
+ super
470
+ end
471
+
358
472
  # Create a trigger in the database. Arguments:
359
473
  # table :: the table on which this trigger operates
360
474
  # name :: the name of this trigger
@@ -365,6 +479,7 @@ module Sequel
365
479
  # :each_row :: Calls the trigger for each row instead of for each statement.
366
480
  # :events :: Can be :insert, :update, :delete, or an array of any of those. Calls the trigger whenever that type of statement is used. By default,
367
481
  # the trigger is called for insert, update, or delete.
482
+ # :replace :: Replace the trigger with the same name if it already exists (PostgreSQL 14+).
368
483
  # :when :: A filter to use for the trigger
369
484
  def create_trigger(table, name, function, opts=OPTS)
370
485
  self << create_trigger_sql(table, name, function, opts)
@@ -667,7 +782,7 @@ module Sequel
667
782
  return @server_version if @server_version
668
783
  ds = dataset
669
784
  ds = ds.server(server) if server
670
- @server_version ||= ds.with_sql("SELECT CAST(current_setting('server_version_num') AS integer) AS v").single_value rescue 0
785
+ @server_version = swallow_database_error{ds.with_sql("SELECT CAST(current_setting('server_version_num') AS integer) AS v").single_value} || 0
671
786
  end
672
787
 
673
788
  # PostgreSQL supports CREATE TABLE IF NOT EXISTS on 9.1+
@@ -732,7 +847,7 @@ module Sequel
732
847
  # :schema :: The schema to search
733
848
  # :server :: The server to use
734
849
  def tables(opts=OPTS, &block)
735
- pg_class_relname('r', opts, &block)
850
+ pg_class_relname(['r', 'p'], opts, &block)
736
851
  end
737
852
 
738
853
  # Check whether the given type name string/symbol (e.g. :hstore) is supported by
@@ -836,10 +951,14 @@ module Sequel
836
951
  # default value is given.
837
952
  def column_definition_default_sql(sql, column)
838
953
  super
839
- if !column[:serial] && !['serial', 'bigserial'].include?(column[:type].to_s) && !column[:default] && (identity = column[:identity])
840
- sql << " GENERATED "
841
- sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
842
- sql << " AS IDENTITY"
954
+ if !column[:serial] && !['smallserial', 'serial', 'bigserial'].include?(column[:type].to_s) && !column[:default]
955
+ if (identity = column[:identity])
956
+ sql << " GENERATED "
957
+ sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
958
+ sql << " AS IDENTITY"
959
+ elsif (generated = column[:generated_always_as])
960
+ sql << " GENERATED ALWAYS AS (#{literal(generated)}) STORED"
961
+ end
843
962
  end
844
963
  end
845
964
 
@@ -1010,6 +1129,36 @@ module Sequel
1010
1129
  "CREATE#{' OR REPLACE' if opts[:replace] && server_version >= 90000}#{' TRUSTED' if opts[:trusted]} LANGUAGE #{name}#{" HANDLER #{opts[:handler]}" if opts[:handler]}#{" VALIDATOR #{opts[:validator]}" if opts[:validator]}"
1011
1130
  end
1012
1131
 
1132
+ # Create a partition of another table, used when the create_table with
1133
+ # the :partition_of option is given.
1134
+ def create_partition_of_table_from_generator(name, generator, options)
1135
+ execute_ddl(create_partition_of_table_sql(name, generator, options))
1136
+ end
1137
+
1138
+ # SQL for creating a partition of another table.
1139
+ def create_partition_of_table_sql(name, generator, options)
1140
+ sql = create_table_prefix_sql(name, options).dup
1141
+
1142
+ sql << " PARTITION OF #{quote_schema_table(options[:partition_of])}"
1143
+
1144
+ case generator.partition_type
1145
+ when :range
1146
+ from, to = generator.range
1147
+ sql << " FOR VALUES FROM #{literal(from)} TO #{literal(to)}"
1148
+ when :list
1149
+ sql << " FOR VALUES IN #{literal(generator.list)}"
1150
+ when :hash
1151
+ mod, remainder = generator.hash_values
1152
+ sql << " FOR VALUES WITH (MODULUS #{literal(mod)}, REMAINDER #{literal(remainder)})"
1153
+ when :default
1154
+ sql << " DEFAULT"
1155
+ end
1156
+
1157
+ sql << create_table_suffix_sql(name, options)
1158
+
1159
+ sql
1160
+ end
1161
+
1013
1162
  # SQL for creating a schema.
1014
1163
  def create_schema_sql(name, opts=OPTS)
1015
1164
  "CREATE SCHEMA #{'IF NOT EXISTS ' if opts[:if_not_exists]}#{quote_identifier(name)}#{" AUTHORIZATION #{literal(opts[:owner])}" if opts[:owner]}"
@@ -1031,25 +1180,36 @@ module Sequel
1031
1180
  "CREATE #{prefix_sql}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
1032
1181
  end
1033
1182
 
1183
+ # SQL for creating a table with PostgreSQL specific options
1034
1184
  def create_table_sql(name, generator, options)
1035
- sql = super
1185
+ "#{super}#{create_table_suffix_sql(name, options)}"
1186
+ end
1187
+
1188
+ # Handle various PostgreSQl specific table extensions such as inheritance,
1189
+ # partitioning, tablespaces, and foreign tables.
1190
+ def create_table_suffix_sql(name, options)
1191
+ sql = String.new
1036
1192
 
1037
1193
  if inherits = options[:inherits]
1038
- sql += " INHERITS (#{Array(inherits).map{|t| quote_schema_table(t)}.join(', ')})"
1194
+ sql << " INHERITS (#{Array(inherits).map{|t| quote_schema_table(t)}.join(', ')})"
1195
+ end
1196
+
1197
+ if partition_by = options[:partition_by]
1198
+ sql << " PARTITION BY #{options[:partition_type]||'RANGE'} #{literal(Array(partition_by))}"
1039
1199
  end
1040
1200
 
1041
1201
  if on_commit = options[:on_commit]
1042
1202
  raise(Error, "can't provide :on_commit without :temp to create_table") unless options[:temp]
1043
1203
  raise(Error, "unsupported on_commit option: #{on_commit.inspect}") unless ON_COMMIT.has_key?(on_commit)
1044
- sql += " ON COMMIT #{ON_COMMIT[on_commit]}"
1204
+ sql << " ON COMMIT #{ON_COMMIT[on_commit]}"
1045
1205
  end
1046
1206
 
1047
1207
  if tablespace = options[:tablespace]
1048
- sql += " TABLESPACE #{quote_identifier(tablespace)}"
1208
+ sql << " TABLESPACE #{quote_identifier(tablespace)}"
1049
1209
  end
1050
1210
 
1051
1211
  if server = options[:foreign]
1052
- sql += " SERVER #{quote_identifier(server)}"
1212
+ sql << " SERVER #{quote_identifier(server)}"
1053
1213
  if foreign_opts = options[:options]
1054
1214
  sql << " OPTIONS (#{foreign_opts.map{|k, v| "#{k} #{literal(v.to_s)}"}.join(', ')})"
1055
1215
  end
@@ -1078,7 +1238,7 @@ module Sequel
1078
1238
  raise Error, "Trigger conditions are not supported for this database" unless supports_trigger_conditions?
1079
1239
  filter = " WHEN #{filter_expr(filter)}"
1080
1240
  end
1081
- "CREATE TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]}#{filter} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
1241
+ "CREATE #{'OR REPLACE ' if opts[:replace]}TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]}#{filter} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
1082
1242
  end
1083
1243
 
1084
1244
  # DDL fragment for initial part of CREATE VIEW statement
@@ -1176,7 +1336,7 @@ module Sequel
1176
1336
  ds = metadata_dataset.from(:pg_class).where(:relkind=>type).select(:relname).server(opts[:server]).join(:pg_namespace, :oid=>:relnamespace)
1177
1337
  ds = filter_schema(ds, opts)
1178
1338
  m = output_identifier_meth
1179
- if block_given?
1339
+ if defined?(yield)
1180
1340
  yield(ds)
1181
1341
  elsif opts[:qualify]
1182
1342
  ds.select_append{pg_namespace[:nspname]}.map{|r| Sequel.qualify(m.call(r[:nspname]).to_s, m.call(r[:relname]).to_s)}
@@ -1265,6 +1425,10 @@ module Sequel
1265
1425
 
1266
1426
  if server_version > 100000
1267
1427
  ds = ds.select_append{pg_attribute[:attidentity]}
1428
+
1429
+ if server_version > 120000
1430
+ ds = ds.select_append{Sequel.~(pg_attribute[:attgenerated]=>'').as(:generated)}
1431
+ end
1268
1432
  end
1269
1433
 
1270
1434
  ds.map do |row|
@@ -1337,9 +1501,11 @@ module Sequel
1337
1501
  # disallowed or there is a size specified, use the varchar type.
1338
1502
  # Otherwise use the text type.
1339
1503
  def type_literal_generic_string(column)
1340
- if column[:fixed]
1504
+ if column[:text]
1505
+ :text
1506
+ elsif column[:fixed]
1341
1507
  "char(#{column[:size]||255})"
1342
- elsif column[:text] == false or column[:size]
1508
+ elsif column[:text] == false || column[:size]
1343
1509
  "varchar(#{column[:size]||255})"
1344
1510
  else
1345
1511
  :text
@@ -1562,13 +1728,22 @@ module Sequel
1562
1728
  ds.insert_sql(*values)
1563
1729
  end
1564
1730
 
1731
+ # Support SQL::AliasedExpression as expr to setup a USING join with a table alias for the
1732
+ # USING columns.
1733
+ def join_table(type, table, expr=nil, options=OPTS, &block)
1734
+ if expr.is_a?(SQL::AliasedExpression) && expr.expression.is_a?(Array) && !expr.expression.empty? && expr.expression.all?
1735
+ options = options.merge(:join_using=>true)
1736
+ end
1737
+ super
1738
+ end
1739
+
1565
1740
  # Locks all tables in the dataset's FROM clause (but not in JOINs) with
1566
1741
  # the specified mode (e.g. 'EXCLUSIVE'). If a block is given, starts
1567
1742
  # a new transaction, locks the table, and yields. If a block is not given,
1568
1743
  # just locks the tables. Note that PostgreSQL will probably raise an error
1569
1744
  # if you lock the table outside of an existing transaction. Returns nil.
1570
1745
  def lock(mode, opts=OPTS)
1571
- if block_given? # perform locking inside a transaction and yield to block
1746
+ if defined?(yield) # perform locking inside a transaction and yield to block
1572
1747
  @db.transaction(opts){lock(mode, opts); yield}
1573
1748
  else
1574
1749
  sql = 'LOCK TABLE '.dup
@@ -1722,6 +1897,13 @@ module Sequel
1722
1897
  end
1723
1898
  end
1724
1899
 
1900
+ # Use WITH TIES when limiting the result set to also include additional
1901
+ # rules that have the same results for the order column as the final row.
1902
+ # Requires PostgreSQL 13.
1903
+ def with_ties
1904
+ clone(:limit_with_ties=>true)
1905
+ end
1906
+
1725
1907
  protected
1726
1908
 
1727
1909
  # If returned primary keys are requested, use RETURNING unless already set on the
@@ -1743,6 +1925,14 @@ module Sequel
1743
1925
  end
1744
1926
  end
1745
1927
 
1928
+ def to_prepared_statement(type, *a)
1929
+ if type == :insert && !@opts.has_key?(:returning)
1930
+ returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
1931
+ else
1932
+ super
1933
+ end
1934
+ end
1935
+
1746
1936
  private
1747
1937
 
1748
1938
  # Format TRUNCATE statement with PostgreSQL specific options.
@@ -1798,6 +1988,16 @@ module Sequel
1798
1988
  end
1799
1989
  end
1800
1990
 
1991
+ # Include aliases when inserting into a single table on PostgreSQL 9.5+.
1992
+ def insert_into_sql(sql)
1993
+ sql << " INTO "
1994
+ if (f = @opts[:from]) && f.length == 1
1995
+ identifier_append(sql, server_version >= 90500 ? f.first : unaliased_identifier(f.first))
1996
+ else
1997
+ source_list_append(sql, f)
1998
+ end
1999
+ end
2000
+
1801
2001
  # Return the primary key to use for RETURNING in an INSERT statement
1802
2002
  def insert_pk
1803
2003
  if (f = opts[:from]) && !f.empty?
@@ -1833,6 +2033,17 @@ module Sequel
1833
2033
  end
1834
2034
  end
1835
2035
 
2036
+ # Support table aliases for USING columns
2037
+ def join_using_clause_using_sql_append(sql, using_columns)
2038
+ if using_columns.is_a?(SQL::AliasedExpression)
2039
+ super(sql, using_columns.expression)
2040
+ sql << ' AS '
2041
+ identifier_append(sql, using_columns.alias)
2042
+ else
2043
+ super
2044
+ end
2045
+ end
2046
+
1836
2047
  # Use a generic blob quoting method, hopefully overridden in one of the subadapter methods
1837
2048
  def literal_blob_append(sql, v)
1838
2049
  sql << "'" << v.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{("%o" % b[0..1].unpack("C")[0]).rjust(3, '0')}"} << "'"
@@ -1890,6 +2101,37 @@ module Sequel
1890
2101
  false
1891
2102
  end
1892
2103
 
2104
+ # Support FETCH FIRST WITH TIES on PostgreSQL 13+.
2105
+ def select_limit_sql(sql)
2106
+ l = @opts[:limit]
2107
+ o = @opts[:offset]
2108
+
2109
+ return unless l || o
2110
+
2111
+ if @opts[:limit_with_ties]
2112
+ if o
2113
+ sql << " OFFSET "
2114
+ literal_append(sql, o)
2115
+ end
2116
+
2117
+ if l
2118
+ sql << " FETCH FIRST "
2119
+ literal_append(sql, l)
2120
+ sql << " ROWS WITH TIES"
2121
+ end
2122
+ else
2123
+ if l
2124
+ sql << " LIMIT "
2125
+ literal_append(sql, l)
2126
+ end
2127
+
2128
+ if o
2129
+ sql << " OFFSET "
2130
+ literal_append(sql, o)
2131
+ end
2132
+ end
2133
+ end
2134
+
1893
2135
  # Support FOR SHARE locking when using the :share lock style.
1894
2136
  # Use SKIP LOCKED if skipping locked rows.
1895
2137
  def select_lock_sql(sql)
@@ -1925,19 +2167,16 @@ module Sequel
1925
2167
  db.server_version(@opts[:server])
1926
2168
  end
1927
2169
 
2170
+ # PostgreSQL 9.4+ supports the FILTER clause for aggregate functions.
2171
+ def supports_filtered_aggregates?
2172
+ server_version >= 90400
2173
+ end
2174
+
1928
2175
  # PostgreSQL supports quoted function names.
1929
2176
  def supports_quoted_function_names?
1930
2177
  true
1931
2178
  end
1932
2179
 
1933
- def to_prepared_statement(type, *a)
1934
- if type == :insert && !@opts.has_key?(:returning)
1935
- returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
1936
- else
1937
- super
1938
- end
1939
- end
1940
-
1941
2180
  # Concatenate the expressions with a space in between
1942
2181
  def full_text_string_join(cols)
1943
2182
  cols = Array(cols).map{|x| SQL::Function.new(:COALESCE, x, '')}
@@ -23,15 +23,6 @@ module Sequel
23
23
  to_application_timestamp(v.to_s) if v
24
24
  end
25
25
 
26
- # Convert smallint type to boolean if convert_smallint_to_bool is true
27
- def schema_column_type(db_type)
28
- if convert_smallint_to_bool && db_type =~ /smallint/i
29
- :boolean
30
- else
31
- super
32
- end
33
- end
34
-
35
26
  def schema_parse_table(table, opts)
36
27
  m = output_identifier_meth(opts[:dataset])
37
28
  im = input_identifier_meth(opts[:dataset])
@@ -216,6 +207,15 @@ module Sequel
216
207
  "ALTER TABLE #{quote_schema_table(name)} RENAME #{quote_schema_table(new_name)}"
217
208
  end
218
209
 
210
+ # Convert smallint type to boolean if convert_smallint_to_bool is true
211
+ def schema_column_type(db_type)
212
+ if convert_smallint_to_bool && db_type =~ /smallint/i
213
+ :boolean
214
+ else
215
+ super
216
+ end
217
+ end
218
+
219
219
  def tables_and_views(type, opts=OPTS)
220
220
  m = output_identifier_meth
221
221
  metadata_dataset.