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
@@ -103,12 +103,18 @@ module Sequel
103
103
  map{|r| m.call(r[:view_name])}
104
104
  end
105
105
 
106
- def view_exists?(name)
107
- m = input_identifier_meth
108
- metadata_dataset.from(:all_views).
109
- exclude(:owner=>IGNORE_OWNERS).
110
- where(:view_name=>m.call(name)).
111
- count > 0
106
+ # Whether a view with a given name exists. By default, looks in all schemas other than system
107
+ # schemas. If the :current_schema option is given, looks in the schema for the current user.
108
+ def view_exists?(name, opts=OPTS)
109
+ ds = metadata_dataset.from(:all_views).where(:view_name=>input_identifier_meth.call(name))
110
+
111
+ if opts[:current_schema]
112
+ ds = ds.where(:owner=>Sequel.function(:SYS_CONTEXT, 'userenv', 'current_schema'))
113
+ else
114
+ ds = ds.exclude(:owner=>IGNORE_OWNERS)
115
+ end
116
+
117
+ ds.count > 0
112
118
  end
113
119
 
114
120
  # The version of the Oracle server, used for determining capability.
@@ -178,7 +184,7 @@ module Sequel
178
184
 
179
185
  def create_table_from_generator(name, generator, options)
180
186
  drop_statement, create_statements = create_table_sql_list(name, generator, options)
181
- (execute_ddl(drop_statement) rescue nil) if drop_statement
187
+ swallow_database_error{execute_ddl(drop_statement)} if drop_statement
182
188
  create_statements.each{|sql| execute_ddl(sql)}
183
189
  end
184
190
 
@@ -422,22 +428,6 @@ module Sequel
422
428
  end
423
429
  end
424
430
 
425
- def select_limit_sql(sql)
426
- return unless supports_fetch_next_rows?
427
-
428
- if offset = @opts[:offset]
429
- sql << " OFFSET "
430
- literal_append(sql, offset)
431
- sql << " ROWS"
432
- end
433
-
434
- if limit = @opts[:limit]
435
- sql << " FETCH NEXT "
436
- literal_append(sql, limit)
437
- sql << " ROWS ONLY"
438
- end
439
- end
440
-
441
431
  # Oracle requires recursive CTEs to have column aliases.
442
432
  def recursive_cte_requires_column_aliases?
443
433
  true
@@ -624,6 +614,22 @@ module Sequel
624
614
  :union
625
615
  end
626
616
 
617
+ def select_limit_sql(sql)
618
+ return unless supports_fetch_next_rows?
619
+
620
+ if offset = @opts[:offset]
621
+ sql << " OFFSET "
622
+ literal_append(sql, offset)
623
+ sql << " ROWS"
624
+ end
625
+
626
+ if limit = @opts[:limit]
627
+ sql << " FETCH NEXT "
628
+ literal_append(sql, limit)
629
+ sql << " ROWS ONLY"
630
+ end
631
+ end
632
+
627
633
  # Use SKIP LOCKED if skipping locked rows.
628
634
  def select_lock_sql(sql)
629
635
  super
@@ -23,44 +23,48 @@ module Sequel
23
23
  PLUS_INFINITY = 1.0/0.0
24
24
  MINUS_INFINITY = -1.0/0.0
25
25
 
26
- TYPE_TRANSLATOR = tt = Class.new do
27
- def boolean(s) s == 't' end
28
- def integer(s) s.to_i end
29
- def float(s)
30
- case s
31
- when 'NaN'
32
- NAN
33
- when 'Infinity'
34
- PLUS_INFINITY
35
- when '-Infinity'
36
- MINUS_INFINITY
37
- else
38
- s.to_f
39
- end
40
- end
41
- def date(s) ::Date.new(*s.split('-').map(&:to_i)) end
42
- def bytea(str)
43
- str = if str =~ /\A\\x/
44
- # PostgreSQL 9.0+ bytea hex format
45
- str[2..-1].gsub(/(..)/){|s| s.to_i(16).chr}
46
- else
47
- # Historical PostgreSQL bytea escape format
48
- str.gsub(/\\(\\|'|[0-3][0-7][0-7])/) {|s|
49
- if s.size == 2 then s[1,1] else s[1,3].oct.chr end
50
- }
51
- end
52
- ::Sequel::SQL::Blob.new(str)
26
+ boolean = Object.new
27
+ def boolean.call(s) s == 't' end
28
+ integer = Object.new
29
+ def integer.call(s) s.to_i end
30
+ float = Object.new
31
+ def float.call(s)
32
+ case s
33
+ when 'NaN'
34
+ NAN
35
+ when 'Infinity'
36
+ PLUS_INFINITY
37
+ when '-Infinity'
38
+ MINUS_INFINITY
39
+ else
40
+ s.to_f
53
41
  end
54
- end.new.freeze
42
+ end
43
+ date = Object.new
44
+ def date.call(s) ::Date.new(*s.split('-').map(&:to_i)) end
45
+ TYPE_TRANSLATOR_DATE = date.freeze
46
+ bytea = Object.new
47
+ def bytea.call(str)
48
+ str = if str =~ /\A\\x/
49
+ # PostgreSQL 9.0+ bytea hex format
50
+ str[2..-1].gsub(/(..)/){|s| s.to_i(16).chr}
51
+ else
52
+ # Historical PostgreSQL bytea escape format
53
+ str.gsub(/\\(\\|'|[0-3][0-7][0-7])/) {|s|
54
+ if s.size == 2 then s[1,1] else s[1,3].oct.chr end
55
+ }
56
+ end
57
+ ::Sequel::SQL::Blob.new(str)
58
+ end
55
59
 
56
60
  CONVERSION_PROCS = {}
57
61
 
58
62
  {
59
- [16] => tt.method(:boolean),
60
- [17] => tt.method(:bytea),
61
- [20, 21, 23, 26] => tt.method(:integer),
62
- [700, 701] => tt.method(:float),
63
- [1700] => ::BigDecimal.method(:new),
63
+ [16] => boolean,
64
+ [17] => bytea,
65
+ [20, 21, 23, 26] => integer,
66
+ [700, 701] => float,
67
+ [1700] => ::Kernel.method(:BigDecimal),
64
68
  [1083, 1266] => ::Sequel.method(:string_to_time),
65
69
  [1082] => ::Sequel.method(:string_to_date),
66
70
  [1184, 1114] => ::Sequel.method(:database_to_application_timestamp),
@@ -93,13 +97,17 @@ module Sequel
93
97
  # Add an exclusion constraint when creating the table. Elements should be
94
98
  # an array of 2 element arrays, with the first element being the column or
95
99
  # expression the exclusion constraint is applied to, and the second element
96
- # being the operator to use for the column/expression to check for exclusion.
97
- #
98
- # Example:
100
+ # being the operator to use for the column/expression to check for exclusion:
99
101
  #
100
102
  # exclude([[:col1, '&&'], [:col2, '=']])
101
103
  # # EXCLUDE USING gist (col1 WITH &&, col2 WITH =)
102
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
+ #
103
111
  # Options supported:
104
112
  #
105
113
  # :name :: Name the constraint with the given name (useful if you may
@@ -126,6 +134,96 @@ module Sequel
126
134
  end
127
135
  end
128
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
+
129
227
  # Error raised when Sequel determines a PostgreSQL exclusion constraint has been violated.
130
228
  class ExclusionConstraintViolation < Sequel::ConstraintViolation; end
131
229
 
@@ -143,10 +241,10 @@ module Sequel
143
241
  SELECT_CUSTOM_SEQUENCE_SQL = (<<-end_sql
144
242
  SELECT name.nspname AS "schema",
145
243
  CASE
146
- WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
147
- substr(split_part(def.adsrc, '''', 2),
148
- strpos(split_part(def.adsrc, '''', 2), '.')+1)
149
- 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)
150
248
  END AS "sequence"
151
249
  FROM pg_class t
152
250
  JOIN pg_namespace name ON (t.relnamespace = name.oid)
@@ -154,7 +252,7 @@ module Sequel
154
252
  JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
155
253
  JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
156
254
  WHERE cons.contype = 'p'
157
- AND def.adsrc ~* 'nextval'
255
+ AND pg_get_expr(def.adbin, attr.attrelid) ~* 'nextval'
158
256
  end_sql
159
257
  ).strip.gsub(/\s+/, ' ').freeze
160
258
 
@@ -195,8 +293,8 @@ module Sequel
195
293
 
196
294
  # Set a conversion proc for the given oid. The callable can
197
295
  # be passed either as a argument or a block.
198
- def add_conversion_proc(oid, callable=Proc.new)
199
- conversion_procs[oid] = callable
296
+ def add_conversion_proc(oid, callable=nil, &block)
297
+ conversion_procs[oid] = callable || block
200
298
  end
201
299
 
202
300
  # Add a conversion proc for a named type, using the given block.
@@ -216,24 +314,22 @@ module Sequel
216
314
  # A hash of metadata for CHECK constraints on the table.
217
315
  # Keys are CHECK constraint name symbols. Values are hashes with the following keys:
218
316
  # :definition :: An SQL fragment for the definition of the constraint
219
- # :columns :: An array of column symbols for the columns referenced in the constraint
317
+ # :columns :: An array of column symbols for the columns referenced in the constraint,
318
+ # can be an empty array if the database cannot deteremine the column symbols.
220
319
  def check_constraints(table)
221
320
  m = output_identifier_meth
222
321
 
223
322
  rows = metadata_dataset.
224
323
  from{pg_constraint.as(:co)}.
225
- join(Sequel[:pg_attribute].as(:att), :attrelid=>:conrelid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
324
+ left_join(Sequel[:pg_attribute].as(:att), :attrelid=>:conrelid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
226
325
  where(:conrelid=>regclass_oid(table), :contype=>'c').
227
326
  select{[co[:conname].as(:constraint), att[:attname].as(:column), pg_get_constraintdef(co[:oid]).as(:definition)]}
228
327
 
229
328
  hash = {}
230
329
  rows.each do |row|
231
330
  constraint = m.call(row[:constraint])
232
- if entry = hash[constraint]
233
- entry[:columns] << m.call(row[:column])
234
- else
235
- hash[constraint] = {:definition=>row[:definition], :columns=>[m.call(row[:column])]}
236
- end
331
+ entry = hash[constraint] ||= {:definition=>row[:definition], :columns=>[]}
332
+ entry[:columns] << m.call(row[:column]) if row[:column]
237
333
  end
238
334
 
239
335
  hash
@@ -261,7 +357,7 @@ module Sequel
261
357
  raise Error, "convert_serial_to_identity is only supported on PostgreSQL 10.2+" unless server_version >= 100002
262
358
 
263
359
  server = opts[:server]
264
- server_hash = server ? {:server=>server} : {}
360
+ server_hash = server ? {:server=>server} : OPTS
265
361
  ds = dataset
266
362
  ds = ds.server(server) if server
267
363
 
@@ -269,7 +365,7 @@ module Sequel
269
365
 
270
366
  table_oid = regclass_oid(table)
271
367
  im = input_identifier_meth
272
- unless column = im.call(opts[:column] || ((sch = schema(table).find{|col, sch| sch[:primary_key] && sch[:auto_increment]}) && sch[0]))
368
+ unless column = im.call(opts[:column] || ((sch = schema(table).find{|_, sc| sc[:primary_key] && sc[:auto_increment]}) && sch[0]))
273
369
  raise Error, "could not determine column to convert from serial to identity automatically"
274
370
  end
275
371
 
@@ -353,6 +449,26 @@ module Sequel
353
449
  self << create_schema_sql(name, opts)
354
450
  end
355
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
+
356
472
  # Create a trigger in the database. Arguments:
357
473
  # table :: the table on which this trigger operates
358
474
  # name :: the name of this trigger
@@ -482,6 +598,10 @@ module Sequel
482
598
  nsp[:nspname].as(:schema)
483
599
  ]}
484
600
 
601
+ if reverse
602
+ ds = ds.order_append(Sequel[:nsp][:nspname], Sequel[:cl2][:relname])
603
+ end
604
+
485
605
  h = {}
486
606
  fklod_map = FOREIGN_KEY_LIST_ON_DELETE_MAP
487
607
 
@@ -661,7 +781,7 @@ module Sequel
661
781
  return @server_version if @server_version
662
782
  ds = dataset
663
783
  ds = ds.server(server) if server
664
- @server_version ||= ds.with_sql("SELECT CAST(current_setting('server_version_num') AS integer) AS v").single_value rescue 0
784
+ @server_version = swallow_database_error{ds.with_sql("SELECT CAST(current_setting('server_version_num') AS integer) AS v").single_value} || 0
665
785
  end
666
786
 
667
787
  # PostgreSQL supports CREATE TABLE IF NOT EXISTS on 9.1+
@@ -830,10 +950,14 @@ module Sequel
830
950
  # default value is given.
831
951
  def column_definition_default_sql(sql, column)
832
952
  super
833
- if !column[:serial] && !['serial', 'bigserial'].include?(column[:type].to_s) && !column[:default] && (identity = column[:identity])
834
- sql << " GENERATED "
835
- sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
836
- sql << " AS IDENTITY"
953
+ if !column[:serial] && !['smallserial', 'serial', 'bigserial'].include?(column[:type].to_s) && !column[:default]
954
+ if (identity = column[:identity])
955
+ sql << " GENERATED "
956
+ sql << (identity == :always ? "ALWAYS" : "BY DEFAULT")
957
+ sql << " AS IDENTITY"
958
+ elsif (generated = column[:generated_always_as])
959
+ sql << " GENERATED ALWAYS AS (#{literal(generated)}) STORED"
960
+ end
837
961
  end
838
962
  end
839
963
 
@@ -1004,6 +1128,36 @@ module Sequel
1004
1128
  "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]}"
1005
1129
  end
1006
1130
 
1131
+ # Create a partition of another table, used when the create_table with
1132
+ # the :partition_of option is given.
1133
+ def create_partition_of_table_from_generator(name, generator, options)
1134
+ execute_ddl(create_partition_of_table_sql(name, generator, options))
1135
+ end
1136
+
1137
+ # SQL for creating a partition of another table.
1138
+ def create_partition_of_table_sql(name, generator, options)
1139
+ sql = create_table_prefix_sql(name, options).dup
1140
+
1141
+ sql << " PARTITION OF #{quote_schema_table(options[:partition_of])}"
1142
+
1143
+ case generator.partition_type
1144
+ when :range
1145
+ from, to = generator.range
1146
+ sql << " FOR VALUES FROM #{literal(from)} TO #{literal(to)}"
1147
+ when :list
1148
+ sql << " FOR VALUES IN #{literal(generator.list)}"
1149
+ when :hash
1150
+ mod, remainder = generator.hash_values
1151
+ sql << " FOR VALUES WITH (MODULUS #{literal(mod)}, REMAINDER #{literal(remainder)})"
1152
+ when :default
1153
+ sql << " DEFAULT"
1154
+ end
1155
+
1156
+ sql << create_table_suffix_sql(name, options)
1157
+
1158
+ sql
1159
+ end
1160
+
1007
1161
  # SQL for creating a schema.
1008
1162
  def create_schema_sql(name, opts=OPTS)
1009
1163
  "CREATE SCHEMA #{'IF NOT EXISTS ' if opts[:if_not_exists]}#{quote_identifier(name)}#{" AUTHORIZATION #{literal(opts[:owner])}" if opts[:owner]}"
@@ -1025,21 +1179,36 @@ module Sequel
1025
1179
  "CREATE #{prefix_sql}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
1026
1180
  end
1027
1181
 
1182
+ # SQL for creating a table with PostgreSQL specific options
1028
1183
  def create_table_sql(name, generator, options)
1029
- sql = super
1184
+ "#{super}#{create_table_suffix_sql(name, options)}"
1185
+ end
1186
+
1187
+ # Handle various PostgreSQl specific table extensions such as inheritance,
1188
+ # partitioning, tablespaces, and foreign tables.
1189
+ def create_table_suffix_sql(name, options)
1190
+ sql = String.new
1030
1191
 
1031
1192
  if inherits = options[:inherits]
1032
- sql += " INHERITS (#{Array(inherits).map{|t| quote_schema_table(t)}.join(', ')})"
1193
+ sql << " INHERITS (#{Array(inherits).map{|t| quote_schema_table(t)}.join(', ')})"
1194
+ end
1195
+
1196
+ if partition_by = options[:partition_by]
1197
+ sql << " PARTITION BY #{options[:partition_type]||'RANGE'} #{literal(Array(partition_by))}"
1033
1198
  end
1034
1199
 
1035
1200
  if on_commit = options[:on_commit]
1036
1201
  raise(Error, "can't provide :on_commit without :temp to create_table") unless options[:temp]
1037
1202
  raise(Error, "unsupported on_commit option: #{on_commit.inspect}") unless ON_COMMIT.has_key?(on_commit)
1038
- sql += " ON COMMIT #{ON_COMMIT[on_commit]}"
1203
+ sql << " ON COMMIT #{ON_COMMIT[on_commit]}"
1204
+ end
1205
+
1206
+ if tablespace = options[:tablespace]
1207
+ sql << " TABLESPACE #{quote_identifier(tablespace)}"
1039
1208
  end
1040
1209
 
1041
1210
  if server = options[:foreign]
1042
- sql += " SERVER #{quote_identifier(server)}"
1211
+ sql << " SERVER #{quote_identifier(server)}"
1043
1212
  if foreign_opts = options[:options]
1044
1213
  sql << " OPTIONS (#{foreign_opts.map{|k, v| "#{k} #{literal(v.to_s)}"}.join(', ')})"
1045
1214
  end
@@ -1073,7 +1242,13 @@ module Sequel
1073
1242
 
1074
1243
  # DDL fragment for initial part of CREATE VIEW statement
1075
1244
  def create_view_prefix_sql(name, options)
1076
- create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
1245
+ sql = create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
1246
+
1247
+ if tablespace = options[:tablespace]
1248
+ sql += " TABLESPACE #{quote_identifier(tablespace)}"
1249
+ end
1250
+
1251
+ sql
1077
1252
  end
1078
1253
 
1079
1254
  # SQL for dropping a function from the database.
@@ -1143,7 +1318,7 @@ module Sequel
1143
1318
  when :spatial
1144
1319
  index_type = :gist
1145
1320
  end
1146
- "CREATE #{unique}INDEX#{' CONCURRENTLY' if index[:concurrently]}#{if_not_exists} #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{"USING #{index_type} " if index_type}#{expr}#{filter}"
1321
+ "CREATE #{unique}INDEX#{' CONCURRENTLY' if index[:concurrently]}#{if_not_exists} #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{"USING #{index_type} " if index_type}#{expr}#{" INCLUDE #{literal(Array(index[:include]))}" if index[:include]}#{" TABLESPACE #{quote_identifier(index[:tablespace])}" if index[:tablespace]}#{filter}"
1147
1322
  end
1148
1323
 
1149
1324
  # Setup datastructures shared by all postgres adapters.
@@ -1249,6 +1424,10 @@ module Sequel
1249
1424
 
1250
1425
  if server_version > 100000
1251
1426
  ds = ds.select_append{pg_attribute[:attidentity]}
1427
+
1428
+ if server_version > 120000
1429
+ ds = ds.select_append{Sequel.~(pg_attribute[:attgenerated]=>'').as(:generated)}
1430
+ end
1252
1431
  end
1253
1432
 
1254
1433
  ds.map do |row|
@@ -1659,11 +1838,29 @@ module Sequel
1659
1838
  true
1660
1839
  end
1661
1840
 
1841
+ # PostgreSQL 8.4+ supports WINDOW clause.
1842
+ def supports_window_clause?
1843
+ server_version >= 80400
1844
+ end
1845
+
1662
1846
  # PostgreSQL 8.4+ supports window functions
1663
1847
  def supports_window_functions?
1664
1848
  server_version >= 80400
1665
1849
  end
1666
1850
 
1851
+ # Base support added in 8.4, offset supported added in 9.0,
1852
+ # GROUPS and EXCLUDE support added in 11.0.
1853
+ def supports_window_function_frame_option?(option)
1854
+ case option
1855
+ when :rows, :range
1856
+ true
1857
+ when :offset
1858
+ server_version >= 90000
1859
+ when :groups, :exclude
1860
+ server_version >= 110000
1861
+ end
1862
+ end
1863
+
1667
1864
  # Truncates the dataset. Returns nil.
1668
1865
  #
1669
1866
  # Options:
@@ -1688,11 +1885,11 @@ module Sequel
1688
1885
  end
1689
1886
  end
1690
1887
 
1691
- # Return a clone of the dataset with an addition named window that can be
1692
- # referenced in window functions. See {SQL::Window} for a list of options
1693
- # that can be passed in.
1694
- def window(name, opts)
1695
- clone(:window=>(@opts[:window]||[]) + [[name, SQL::Window.new(opts)]])
1888
+ # Use WITH TIES when limiting the result set to also include additional
1889
+ # rules that have the same results for the order column as the final row.
1890
+ # Requires PostgreSQL 13.
1891
+ def with_ties
1892
+ clone(:limit_with_ties=>true)
1696
1893
  end
1697
1894
 
1698
1895
  protected
@@ -1704,7 +1901,9 @@ module Sequel
1704
1901
  def _import(columns, values, opts=OPTS)
1705
1902
  if @opts[:returning]
1706
1903
  statements = multi_insert_sql(columns, values)
1707
- @db.transaction(Hash[opts].merge!(:server=>@opts[:server])) do
1904
+ trans_opts = Hash[opts]
1905
+ trans_opts[:server] = @opts[:server]
1906
+ @db.transaction(trans_opts) do
1708
1907
  statements.map{|st| returning_fetch_rows(st)}
1709
1908
  end.first.map{|v| v.length == 1 ? v.values.first : v}
1710
1909
  elsif opts[:return] == :primary_key
@@ -1714,11 +1913,19 @@ module Sequel
1714
1913
  end
1715
1914
  end
1716
1915
 
1916
+ def to_prepared_statement(type, *a)
1917
+ if type == :insert && !@opts.has_key?(:returning)
1918
+ returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
1919
+ else
1920
+ super
1921
+ end
1922
+ end
1923
+
1717
1924
  private
1718
1925
 
1719
1926
  # Format TRUNCATE statement with PostgreSQL specific options.
1720
1927
  def _truncate_sql(table)
1721
- to = @opts[:truncate_opts] || {}
1928
+ to = @opts[:truncate_opts] || OPTS
1722
1929
  "TRUNCATE TABLE#{' ONLY' if to[:only]} #{table}#{' RESTART IDENTITY' if to[:restart]}#{' CASCADE' if to[:cascade]}"
1723
1930
  end
1724
1931
 
@@ -1769,6 +1976,16 @@ module Sequel
1769
1976
  end
1770
1977
  end
1771
1978
 
1979
+ # Include aliases when inserting into a single table on PostgreSQL 9.5+.
1980
+ def insert_into_sql(sql)
1981
+ sql << " INTO "
1982
+ if (f = @opts[:from]) && f.length == 1
1983
+ identifier_append(sql, server_version >= 90500 ? f.first : unaliased_identifier(f.first))
1984
+ else
1985
+ source_list_append(sql, f)
1986
+ end
1987
+ end
1988
+
1772
1989
  # Return the primary key to use for RETURNING in an INSERT statement
1773
1990
  def insert_pk
1774
1991
  if (f = opts[:from]) && !f.empty?
@@ -1855,6 +2072,43 @@ module Sequel
1855
2072
  sql << ')'
1856
2073
  end
1857
2074
 
2075
+ # Backslash is supported by default as the escape character on PostgreSQL,
2076
+ # and using ESCAPE can break LIKE ANY() usage.
2077
+ def requires_like_escape?
2078
+ false
2079
+ end
2080
+
2081
+ # Support FETCH FIRST WITH TIES on PostgreSQL 13+.
2082
+ def select_limit_sql(sql)
2083
+ l = @opts[:limit]
2084
+ o = @opts[:offset]
2085
+
2086
+ return unless l || o
2087
+
2088
+ if @opts[:limit_with_ties]
2089
+ if o
2090
+ sql << " OFFSET "
2091
+ literal_append(sql, o)
2092
+ end
2093
+
2094
+ if l
2095
+ sql << " FETCH FIRST "
2096
+ literal_append(sql, l)
2097
+ sql << " ROWS WITH TIES"
2098
+ end
2099
+ else
2100
+ if l
2101
+ sql << " LIMIT "
2102
+ literal_append(sql, l)
2103
+ end
2104
+
2105
+ if o
2106
+ sql << " OFFSET "
2107
+ literal_append(sql, o)
2108
+ end
2109
+ end
2110
+ end
2111
+
1858
2112
  # Support FOR SHARE locking when using the :share lock style.
1859
2113
  # Use SKIP LOCKED if skipping locked rows.
1860
2114
  def select_lock_sql(sql)
@@ -1880,46 +2134,38 @@ module Sequel
1880
2134
  expression_list_append(sql, opts[:values])
1881
2135
  end
1882
2136
 
1883
- # SQL fragment for named window specifications
1884
- def select_window_sql(sql)
1885
- if ws = @opts[:window]
1886
- sql << " WINDOW "
1887
- c = false
1888
- co = ', '
1889
- as = ' AS '
1890
- ws.map do |name, window|
1891
- sql << co if c
1892
- literal_append(sql, name)
1893
- sql << as
1894
- literal_append(sql, window)
1895
- c ||= true
1896
- end
1897
- end
1898
- end
1899
-
1900
2137
  # Use WITH RECURSIVE instead of WITH if any of the CTEs is recursive
1901
2138
  def select_with_sql_base
1902
2139
  opts[:with].any?{|w| w[:recursive]} ? "WITH RECURSIVE " : super
1903
2140
  end
1904
2141
 
2142
+ # Support WITH AS [NOT] MATERIALIZED if :materialized option is used.
2143
+ def select_with_sql_prefix(sql, w)
2144
+ super
2145
+
2146
+ case w[:materialized]
2147
+ when true
2148
+ sql << "MATERIALIZED "
2149
+ when false
2150
+ sql << "NOT MATERIALIZED "
2151
+ end
2152
+ end
2153
+
1905
2154
  # The version of the database server
1906
2155
  def server_version
1907
2156
  db.server_version(@opts[:server])
1908
2157
  end
1909
2158
 
2159
+ # PostgreSQL 9.4+ supports the FILTER clause for aggregate functions.
2160
+ def supports_filtered_aggregates?
2161
+ server_version >= 90400
2162
+ end
2163
+
1910
2164
  # PostgreSQL supports quoted function names.
1911
2165
  def supports_quoted_function_names?
1912
2166
  true
1913
2167
  end
1914
2168
 
1915
- def to_prepared_statement(type, *a)
1916
- if type == :insert && !@opts.has_key?(:returning)
1917
- returning(insert_pk).send(:to_prepared_statement, :insert_pk, *a)
1918
- else
1919
- super
1920
- end
1921
- end
1922
-
1923
2169
  # Concatenate the expressions with a space in between
1924
2170
  def full_text_string_join(cols)
1925
2171
  cols = Array(cols).map{|x| SQL::Function.new(:COALESCE, x, '')}