sequel 4.26.0 → 5.37.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 (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  11. data/doc/core_extensions.rdoc +104 -63
  12. data/doc/dataset_basics.rdoc +12 -21
  13. data/doc/dataset_filtering.rdoc +99 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Sequel
2
4
  class Dataset
3
5
  # ---------------------
@@ -15,7 +17,7 @@ module Sequel
15
17
 
16
18
  # Returns an INSERT SQL query string. See +insert+.
17
19
  #
18
- # DB[:items].insert_sql(:a=>1)
20
+ # DB[:items].insert_sql(a: 1)
19
21
  # # => "INSERT INTO items (a) VALUES (1)"
20
22
  def insert_sql(*values)
21
23
  return static_sql(@opts[:sql]) if @opts[:sql]
@@ -26,9 +28,9 @@ module Sequel
26
28
 
27
29
  case values.size
28
30
  when 0
29
- return insert_sql({})
31
+ return insert_sql(OPTS)
30
32
  when 1
31
- case vals = values.at(0)
33
+ case vals = values[0]
32
34
  when Hash
33
35
  values = []
34
36
  vals.each do |k,v|
@@ -39,19 +41,21 @@ module Sequel
39
41
  values = vals
40
42
  end
41
43
  when 2
42
- if (v0 = values.at(0)).is_a?(Array) && ((v1 = values.at(1)).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
44
+ if (v0 = values[0]).is_a?(Array) && ((v1 = values[1]).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
43
45
  columns, values = v0, v1
44
46
  raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
45
47
  end
46
48
  end
47
49
 
48
50
  if values.is_a?(Array) && values.empty? && !insert_supports_empty_values?
49
- columns = [columns().last]
50
- values = [DEFAULT]
51
+ columns, values = insert_empty_columns_values
52
+ elsif values.is_a?(Dataset) && hoist_cte?(values) && supports_cte?(:insert)
53
+ ds, values = hoist_cte(values)
54
+ return ds.clone(:columns=>columns, :values=>values).send(:_insert_sql)
51
55
  end
52
56
  clone(:columns=>columns, :values=>values).send(:_insert_sql)
53
57
  end
54
-
58
+
55
59
  # Append a literal representation of a value to the given SQL string.
56
60
  #
57
61
  # If an unsupported object is given, an +Error+ is raised.
@@ -62,7 +66,7 @@ module Sequel
62
66
  literal_symbol_append(sql, v)
63
67
  else
64
68
  unless l = db.literal_symbol(v)
65
- l = ''
69
+ l = String.new
66
70
  literal_symbol_append(l, v)
67
71
  db.literal_symbol_set(v, l)
68
72
  end
@@ -111,9 +115,6 @@ module Sequel
111
115
  # Returns an array of insert statements for inserting multiple records.
112
116
  # This method is used by +multi_insert+ to format insert statements and
113
117
  # expects a keys array and and an array of value arrays.
114
- #
115
- # This method should be overridden by descendants if the support
116
- # inserting multiple records in a single SQL statement.
117
118
  def multi_insert_sql(columns, values)
118
119
  case multi_insert_sql_strategy
119
120
  when :values
@@ -122,14 +123,14 @@ module Sequel
122
123
  [insert_sql(columns, sql)]
123
124
  when :union
124
125
  c = false
125
- sql = LiteralString.new('')
126
- u = UNION_ALL_SELECT
126
+ sql = LiteralString.new
127
+ u = ' UNION ALL SELECT '
127
128
  f = empty_from_sql
128
129
  values.each do |v|
129
130
  if c
130
131
  sql << u
131
132
  else
132
- sql << SELECT << SPACE
133
+ sql << 'SELECT '
133
134
  c = true
134
135
  end
135
136
  expression_list_append(sql, v)
@@ -154,8 +155,9 @@ module Sequel
154
155
  static_sql(opts[:sql])
155
156
  else
156
157
  check_truncation_allowed!
158
+ check_not_limited!(:truncate)
157
159
  raise(InvalidOperation, "Can't truncate filtered datasets") if opts[:where] || opts[:having]
158
- t = ''
160
+ t = String.new
159
161
  source_list_append(t, opts[:from])
160
162
  _truncate_sql(t)
161
163
  end
@@ -163,7 +165,7 @@ module Sequel
163
165
 
164
166
  # Formats an UPDATE statement using the given values. See +update+.
165
167
  #
166
- # DB[:items].update_sql(:price => 100, :category => 'software')
168
+ # DB[:items].update_sql(price: 100, category: 'software')
167
169
  # # => "UPDATE items SET price = 100, category = 'software'
168
170
  #
169
171
  # Raises an +Error+ if the dataset is grouped or includes more
@@ -171,6 +173,15 @@ module Sequel
171
173
  def update_sql(values = OPTS)
172
174
  return static_sql(opts[:sql]) if opts[:sql]
173
175
  check_modification_allowed!
176
+ check_not_limited!(:update)
177
+
178
+ case values
179
+ when LiteralString
180
+ # nothing
181
+ when String
182
+ raise Error, "plain string passed to Dataset#update is not supported, use Sequel.lit to use a literal string"
183
+ end
184
+
174
185
  clone(:values=>values).send(:_update_sql)
175
186
  end
176
187
 
@@ -197,12 +208,14 @@ module Sequel
197
208
  # being an array of symbol/strings for the appropriate branch.
198
209
  def self.def_sql_method(mod, type, clauses)
199
210
  priv = type == :update || type == :insert
211
+ cacheable = type == :select || type == :delete
200
212
 
201
213
  lines = []
202
214
  lines << 'private' if priv
203
215
  lines << "def #{'_' if priv}#{type}_sql"
204
216
  lines << 'if sql = opts[:sql]; return static_sql(sql) end' unless priv
205
- lines << 'check_modification_allowed!' if type == :delete
217
+ lines << "if sql = cache_get(:_#{type}_sql); return sql end" if cacheable
218
+ lines << 'check_modification_allowed!' << 'check_not_limited!(:delete)' if type == :delete
206
219
  lines << 'sql = @opts[:append_sql] || sql_string_origin'
207
220
 
208
221
  if clauses.all?{|c| c.is_a?(Array)}
@@ -215,6 +228,7 @@ module Sequel
215
228
  lines.concat(clause_methods(type, clauses).map{|x| "#{x}(sql)"})
216
229
  end
217
230
 
231
+ lines << "cache_set(:_#{type}_sql, sql) if cache_sql?" if cacheable
218
232
  lines << 'sql'
219
233
  lines << 'end'
220
234
 
@@ -226,121 +240,26 @@ module Sequel
226
240
  def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order limit lock')
227
241
  def_sql_method(self, :update, %w'update table set where')
228
242
 
229
- # Map of emulated function names to native function names.
230
- EMULATED_FUNCTION_MAP = {}
231
-
232
243
  WILDCARD = LiteralString.new('*').freeze
233
- ALL = ' ALL'.freeze
234
- AND_SEPARATOR = " AND ".freeze
235
- APOS = "'".freeze
236
- APOS_RE = /'/.freeze
237
- ARRAY_EMPTY = '(NULL)'.freeze
238
- AS = ' AS '.freeze
239
- ASC = ' ASC'.freeze
240
- BACKSLASH = "\\".freeze
241
- BITCOMP_CLOSE = ") - 1)".freeze
242
- BITCOMP_OPEN = "((0 - ".freeze
243
- BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR}
244
- BOOL_FALSE = "'f'".freeze
245
- BOOL_TRUE = "'t'".freeze
246
- BRACKET_CLOSE = ']'.freeze
247
- BRACKET_OPEN = '['.freeze
248
- CASE_ELSE = " ELSE ".freeze
249
- CASE_END = " END)".freeze
250
- CASE_OPEN = '(CASE'.freeze
251
- CASE_THEN = " THEN ".freeze
252
- CASE_WHEN = " WHEN ".freeze
253
- CAST_OPEN = 'CAST('.freeze
254
- COLON = ':'.freeze
255
- COLUMN_REF_RE1 = Sequel::COLUMN_REF_RE1
256
- COLUMN_REF_RE2 = Sequel::COLUMN_REF_RE2
257
- COLUMN_REF_RE3 = Sequel::COLUMN_REF_RE3
258
- COMMA = ', '.freeze
259
- COMMA_SEPARATOR = COMMA
260
- CONDITION_FALSE = '(1 = 0)'.freeze
261
- CONDITION_TRUE = '(1 = 1)'.freeze
262
- COUNT_FROM_SELF_OPTS = [:distinct, :group, :sql, :limit, :offset, :compounds]
263
244
  COUNT_OF_ALL_AS_COUNT = SQL::Function.new(:count, WILDCARD).as(:count)
264
- DATASET_ALIAS_BASE_NAME = 't'.freeze
265
245
  DEFAULT = LiteralString.new('DEFAULT').freeze
266
- DEFAULT_VALUES = " DEFAULT VALUES".freeze
267
- DELETE = 'DELETE'.freeze
268
- DESC = ' DESC'.freeze
269
- DISTINCT = " DISTINCT".freeze
270
- DOT = '.'.freeze
271
- DOUBLE_APOS = "''".freeze
272
- DOUBLE_QUOTE = '""'.freeze
273
- EQUAL = ' = '.freeze
274
- EMPTY_PARENS = '()'.freeze
275
- ESCAPE = " ESCAPE ".freeze
276
- EXTRACT = 'extract('.freeze
246
+
277
247
  EXISTS = ['EXISTS '.freeze].freeze
278
- FILTER = " FILTER (WHERE ".freeze
279
- FOR_UPDATE = ' FOR UPDATE'.freeze
280
- FORMAT_DATE = "'%Y-%m-%d'".freeze
281
- FORMAT_DATE_STANDARD = "DATE '%Y-%m-%d'".freeze
282
- FORMAT_OFFSET = "%+03i%02i".freeze
283
- FORMAT_TIMESTAMP_RE = /%[Nz]/.freeze
284
- FORMAT_USEC = '%N'.freeze
285
- FRAME_ALL = "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING".freeze
286
- FRAME_ROWS = "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW".freeze
287
- FROM = ' FROM '.freeze
288
- FUNCTION_DISTINCT = "DISTINCT ".freeze
289
- GROUP_BY = " GROUP BY ".freeze
290
- HAVING = " HAVING ".freeze
291
- INSERT = "INSERT".freeze
292
- INTO = " INTO ".freeze
248
+ BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR}.freeze
249
+ COUNT_FROM_SELF_OPTS = [:distinct, :group, :sql, :limit, :offset, :compounds].freeze
293
250
  IS_LITERALS = {nil=>'NULL'.freeze, true=>'TRUE'.freeze, false=>'FALSE'.freeze}.freeze
251
+ QUALIFY_KEYS = [:select, :where, :having, :order, :group].freeze
252
+
294
253
  IS_OPERATORS = ::Sequel::SQL::ComplexExpression::IS_OPERATORS
295
- LATERAL = 'LATERAL '.freeze
296
254
  LIKE_OPERATORS = ::Sequel::SQL::ComplexExpression::LIKE_OPERATORS
297
- LIMIT = " LIMIT ".freeze
298
255
  N_ARITY_OPERATORS = ::Sequel::SQL::ComplexExpression::N_ARITY_OPERATORS
299
- NOT_SPACE = 'NOT '.freeze
300
- NULL = "NULL".freeze
301
- NULLS_FIRST = " NULLS FIRST".freeze
302
- NULLS_LAST = " NULLS LAST".freeze
303
- OFFSET = " OFFSET ".freeze
304
- ON = ' ON '.freeze
305
- ON_PAREN = " ON (".freeze
306
- ORDER_BY = " ORDER BY ".freeze
307
- ORDER_BY_NS = "ORDER BY ".freeze
308
- OVER = ' OVER '.freeze
309
- PAREN_CLOSE = ')'.freeze
310
- PAREN_OPEN = '('.freeze
311
- PAREN_SPACE_OPEN = ' ('.freeze
312
- PARTITION_BY = "PARTITION BY ".freeze
313
- QUALIFY_KEYS = [:select, :where, :having, :order, :group]
314
- QUESTION_MARK = '?'.freeze
315
- QUESTION_MARK_RE = /\?/.freeze
316
- QUOTE = '"'.freeze
317
- QUOTE_RE = /"/.freeze
318
- RETURNING = " RETURNING ".freeze
319
- SELECT = 'SELECT'.freeze
320
- SET = ' SET '.freeze
321
- SPACE = ' '.freeze
322
- SQL_WITH = "WITH ".freeze
323
- SPACE_WITH = " WITH ".freeze
324
- TILDE = '~'.freeze
325
- TIMESTAMP_FORMAT = "'%Y-%m-%d %H:%M:%S%N%z'".freeze
326
- STANDARD_TIMESTAMP_FORMAT = "TIMESTAMP #{TIMESTAMP_FORMAT}".freeze
327
256
  TWO_ARITY_OPERATORS = ::Sequel::SQL::ComplexExpression::TWO_ARITY_OPERATORS
328
257
  REGEXP_OPERATORS = ::Sequel::SQL::ComplexExpression::REGEXP_OPERATORS
329
- UNDERSCORE = '_'.freeze
330
- UPDATE = 'UPDATE'.freeze
331
- USING = ' USING ('.freeze
332
- UNION_ALL_SELECT = ' UNION ALL SELECT '.freeze
333
- VALUES = " VALUES ".freeze
334
- WHERE = " WHERE ".freeze
335
- WITH_ORDINALITY = " WITH ORDINALITY".freeze
336
- WITHIN_GROUP = " WITHIN GROUP (ORDER BY ".freeze
337
-
338
- DATETIME_SECFRACTION_ARG = RUBY_VERSION >= '1.9.0' ? 1000000 : 86400000000
339
258
 
340
259
  [:literal, :quote_identifier, :quote_schema_table].each do |meth|
341
260
  class_eval(<<-END, __FILE__, __LINE__ + 1)
342
261
  def #{meth}(*args, &block)
343
- s = ''
262
+ s = ''.dup
344
263
  #{meth}_append(s, *args, &block)
345
264
  s
346
265
  end
@@ -356,18 +275,18 @@ module Sequel
356
275
  # Append literalization of array to SQL string.
357
276
  def array_sql_append(sql, a)
358
277
  if a.empty?
359
- sql << ARRAY_EMPTY
278
+ sql << '(NULL)'
360
279
  else
361
- sql << PAREN_OPEN
280
+ sql << '('
362
281
  expression_list_append(sql, a)
363
- sql << PAREN_CLOSE
282
+ sql << ')'
364
283
  end
365
284
  end
366
285
 
367
286
  # Append literalization of boolean constant to SQL string.
368
287
  def boolean_constant_sql_append(sql, constant)
369
288
  if (constant == true || constant == false) && !supports_where_true?
370
- sql << (constant == true ? CONDITION_TRUE : CONDITION_FALSE)
289
+ sql << (constant == true ? '(1 = 1)' : '(1 = 0)')
371
290
  else
372
291
  literal_append(sql, constant)
373
292
  end
@@ -375,30 +294,30 @@ module Sequel
375
294
 
376
295
  # Append literalization of case expression to SQL string.
377
296
  def case_expression_sql_append(sql, ce)
378
- sql << CASE_OPEN
297
+ sql << '(CASE'
379
298
  if ce.expression?
380
- sql << SPACE
299
+ sql << ' '
381
300
  literal_append(sql, ce.expression)
382
301
  end
383
- w = CASE_WHEN
384
- t = CASE_THEN
302
+ w = " WHEN "
303
+ t = " THEN "
385
304
  ce.conditions.each do |c,r|
386
305
  sql << w
387
306
  literal_append(sql, c)
388
307
  sql << t
389
308
  literal_append(sql, r)
390
309
  end
391
- sql << CASE_ELSE
310
+ sql << " ELSE "
392
311
  literal_append(sql, ce.default)
393
- sql << CASE_END
312
+ sql << " END)"
394
313
  end
395
314
 
396
315
  # Append literalization of cast expression to SQL string.
397
316
  def cast_sql_append(sql, expr, type)
398
- sql << CAST_OPEN
317
+ sql << 'CAST('
399
318
  literal_append(sql, expr)
400
- sql << AS << db.cast_type_literal(type).to_s
401
- sql << PAREN_CLOSE
319
+ sql << ' AS ' << db.cast_type_literal(type).to_s
320
+ sql << ')'
402
321
  end
403
322
 
404
323
  # Append literalization of column all selection to SQL string.
@@ -410,21 +329,21 @@ module Sequel
410
329
  def complex_expression_sql_append(sql, op, args)
411
330
  case op
412
331
  when *IS_OPERATORS
413
- r = args.at(1)
332
+ r = args[1]
414
333
  if r.nil? || supports_is_true?
415
334
  raise(InvalidOperation, 'Invalid argument used for IS operator') unless val = IS_LITERALS[r]
416
- sql << PAREN_OPEN
417
- literal_append(sql, args.at(0))
418
- sql << SPACE << op.to_s << SPACE
419
- sql << val << PAREN_CLOSE
335
+ sql << '('
336
+ literal_append(sql, args[0])
337
+ sql << ' ' << op.to_s << ' '
338
+ sql << val << ')'
420
339
  elsif op == :IS
421
340
  complex_expression_sql_append(sql, :"=", args)
422
341
  else
423
- complex_expression_sql_append(sql, :OR, [SQL::BooleanExpression.new(:"!=", *args), SQL::BooleanExpression.new(:IS, args.at(0), nil)])
342
+ complex_expression_sql_append(sql, :OR, [SQL::BooleanExpression.new(:"!=", *args), SQL::BooleanExpression.new(:IS, args[0], nil)])
424
343
  end
425
344
  when :IN, :"NOT IN"
426
- cols = args.at(0)
427
- vals = args.at(1)
345
+ cols = args[0]
346
+ vals = args[1]
428
347
  col_array = true if cols.is_a?(Array)
429
348
  if vals.is_a?(Array)
430
349
  val_array = true
@@ -448,44 +367,48 @@ module Sequel
448
367
  # If the columns and values are both arrays, use array_sql instead of
449
368
  # literal so that if values is an array of two element arrays, it
450
369
  # will be treated as a value list instead of a condition specifier.
451
- sql << PAREN_OPEN
370
+ sql << '('
452
371
  literal_append(sql, cols)
453
- sql << SPACE << op.to_s << SPACE
372
+ sql << ' ' << op.to_s << ' '
454
373
  if val_array
455
374
  array_sql_append(sql, vals)
456
375
  else
457
376
  literal_append(sql, vals)
458
377
  end
459
- sql << PAREN_CLOSE
378
+ sql << ')'
460
379
  end
461
380
  else
462
- sql << PAREN_OPEN
381
+ sql << '('
463
382
  literal_append(sql, cols)
464
- sql << SPACE << op.to_s << SPACE
383
+ sql << ' ' << op.to_s << ' '
465
384
  literal_append(sql, vals)
466
- sql << PAREN_CLOSE
385
+ sql << ')'
467
386
  end
468
387
  when :LIKE, :'NOT LIKE'
469
- sql << PAREN_OPEN
470
- literal_append(sql, args.at(0))
471
- sql << SPACE << op.to_s << SPACE
472
- literal_append(sql, args.at(1))
473
- sql << ESCAPE
474
- literal_append(sql, BACKSLASH)
475
- sql << PAREN_CLOSE
388
+ sql << '('
389
+ literal_append(sql, args[0])
390
+ sql << ' ' << op.to_s << ' '
391
+ literal_append(sql, args[1])
392
+ if requires_like_escape?
393
+ sql << " ESCAPE "
394
+ literal_append(sql, "\\")
395
+ end
396
+ sql << ')'
476
397
  when :ILIKE, :'NOT ILIKE'
477
398
  complex_expression_sql_append(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|v| Sequel.function(:UPPER, v)})
399
+ when :**
400
+ function_sql_append(sql, Sequel.function(:power, *args))
478
401
  when *TWO_ARITY_OPERATORS
479
402
  if REGEXP_OPERATORS.include?(op) && !supports_regexp?
480
403
  raise InvalidOperation, "Pattern matching via regular expressions is not supported on #{db.database_type}"
481
404
  end
482
- sql << PAREN_OPEN
483
- literal_append(sql, args.at(0))
484
- sql << SPACE << op.to_s << SPACE
485
- literal_append(sql, args.at(1))
486
- sql << PAREN_CLOSE
405
+ sql << '('
406
+ literal_append(sql, args[0])
407
+ sql << ' ' << op.to_s << ' '
408
+ literal_append(sql, args[1])
409
+ sql << ')'
487
410
  when *N_ARITY_OPERATORS
488
- sql << PAREN_OPEN
411
+ sql << '('
489
412
  c = false
490
413
  op_str = " #{op} "
491
414
  args.each do |a|
@@ -493,19 +416,19 @@ module Sequel
493
416
  literal_append(sql, a)
494
417
  c ||= true
495
418
  end
496
- sql << PAREN_CLOSE
419
+ sql << ')'
497
420
  when :NOT
498
- sql << NOT_SPACE
499
- literal_append(sql, args.at(0))
421
+ sql << 'NOT '
422
+ literal_append(sql, args[0])
500
423
  when :NOOP
501
- literal_append(sql, args.at(0))
424
+ literal_append(sql, args[0])
502
425
  when :'B~'
503
- sql << TILDE
504
- literal_append(sql, args.at(0))
426
+ sql << '~'
427
+ literal_append(sql, args[0])
505
428
  when :extract
506
- sql << EXTRACT << args.at(0).to_s << FROM
507
- literal_append(sql, args.at(1))
508
- sql << PAREN_CLOSE
429
+ sql << 'extract(' << args[0].to_s << ' FROM '
430
+ literal_append(sql, args[1])
431
+ sql << ')'
509
432
  else
510
433
  raise(InvalidOperation, "invalid operator #{op}")
511
434
  end
@@ -519,6 +442,11 @@ module Sequel
519
442
  # Append literalization of delayed evaluation to SQL string,
520
443
  # causing the delayed evaluation proc to be evaluated.
521
444
  def delayed_evaluation_sql_append(sql, delay)
445
+ # Delayed evaluations are used specifically so the SQL
446
+ # can differ in subsequent calls, so we definitely don't
447
+ # want to cache the sql in this case.
448
+ disable_sql_caching!
449
+
522
450
  if recorder = @opts[:placeholder_literalizer]
523
451
  recorder.use(sql, lambda{delay.call(self)}, nil)
524
452
  else
@@ -540,11 +468,11 @@ module Sequel
540
468
  name = native_function_name(name)
541
469
  end
542
470
 
543
- sql << LATERAL if opts[:lateral]
471
+ sql << 'LATERAL ' if opts[:lateral]
544
472
 
545
473
  case name
546
474
  when SQL::Identifier
547
- if supports_quoted_function_names? && opts[:quoted] != false
475
+ if supports_quoted_function_names? && opts[:quoted]
548
476
  literal_append(sql, name)
549
477
  else
550
478
  sql << name.value.to_s
@@ -553,7 +481,7 @@ module Sequel
553
481
  if supports_quoted_function_names? && opts[:quoted] != false
554
482
  literal_append(sql, name)
555
483
  else
556
- sql << split_qualifiers(name).join(DOT)
484
+ sql << split_qualifiers(name).join('.')
557
485
  end
558
486
  else
559
487
  if supports_quoted_function_names? && opts[:quoted]
@@ -563,34 +491,51 @@ module Sequel
563
491
  end
564
492
  end
565
493
 
566
- sql << PAREN_OPEN
494
+ sql << '('
495
+ if filter = opts[:filter]
496
+ filter = filter_expr(filter, &opts[:filter_block])
497
+ end
567
498
  if opts[:*]
568
- sql << WILDCARD
499
+ if filter && !supports_filtered_aggregates?
500
+ literal_append(sql, Sequel.case({filter=>1}, nil))
501
+ filter = nil
502
+ else
503
+ sql << '*'
504
+ end
569
505
  else
570
- sql << FUNCTION_DISTINCT if opts[:distinct]
571
- expression_list_append(sql, f.args)
506
+ sql << "DISTINCT " if opts[:distinct]
507
+ if filter && !supports_filtered_aggregates?
508
+ expression_list_append(sql, f.args.map{|arg| Sequel.case({filter=>arg}, nil)})
509
+ filter = nil
510
+ else
511
+ expression_list_append(sql, f.args)
512
+ end
513
+ if order = opts[:order]
514
+ sql << " ORDER BY "
515
+ expression_list_append(sql, order)
516
+ end
572
517
  end
573
- sql << PAREN_CLOSE
518
+ sql << ')'
574
519
 
575
520
  if group = opts[:within_group]
576
- sql << WITHIN_GROUP
521
+ sql << " WITHIN GROUP (ORDER BY "
577
522
  expression_list_append(sql, group)
578
- sql << PAREN_CLOSE
523
+ sql << ')'
579
524
  end
580
525
 
581
- if filter = opts[:filter]
582
- sql << FILTER
583
- literal_append(sql, filter_expr(filter, &opts[:filter_block]))
584
- sql << PAREN_CLOSE
526
+ if filter
527
+ sql << " FILTER (WHERE "
528
+ literal_append(sql, filter)
529
+ sql << ')'
585
530
  end
586
531
 
587
532
  if window = opts[:over]
588
- sql << OVER
533
+ sql << ' OVER '
589
534
  window_sql_append(sql, window.opts)
590
535
  end
591
536
 
592
537
  if opts[:with_ordinality]
593
- sql << WITH_ORDINALITY
538
+ sql << " WITH ORDINALITY"
594
539
  end
595
540
  end
596
541
 
@@ -599,7 +544,7 @@ module Sequel
599
544
  table = jc.table
600
545
  table_alias = jc.table_alias
601
546
  table_alias = nil if table == table_alias && !jc.column_aliases
602
- sql << SPACE << join_type_sql(jc.join_type) << SPACE
547
+ sql << ' ' << join_type_sql(jc.join_type) << ' '
603
548
  identifier_append(sql, table)
604
549
  as_sql_append(sql, table_alias, jc.column_aliases) if table_alias
605
550
  end
@@ -607,33 +552,50 @@ module Sequel
607
552
  # Append literalization of JOIN ON clause to SQL string.
608
553
  def join_on_clause_sql_append(sql, jc)
609
554
  join_clause_sql_append(sql, jc)
610
- sql << ON
555
+ sql << ' ON '
611
556
  literal_append(sql, filter_expr(jc.on))
612
557
  end
613
558
 
614
559
  # Append literalization of JOIN USING clause to SQL string.
615
560
  def join_using_clause_sql_append(sql, jc)
616
561
  join_clause_sql_append(sql, jc)
617
- sql << USING
562
+ sql << ' USING ('
618
563
  column_list_append(sql, jc.using)
619
- sql << PAREN_CLOSE
564
+ sql << ')'
620
565
  end
621
566
 
622
567
  # Append literalization of negative boolean constant to SQL string.
623
568
  def negative_boolean_constant_sql_append(sql, constant)
624
- sql << NOT_SPACE
569
+ sql << 'NOT '
625
570
  boolean_constant_sql_append(sql, constant)
626
571
  end
627
572
 
628
573
  # Append literalization of ordered expression to SQL string.
629
574
  def ordered_expression_sql_append(sql, oe)
575
+ if emulate = requires_emulating_nulls_first?
576
+ case oe.nulls
577
+ when :first
578
+ null_order = 0
579
+ when :last
580
+ null_order = 2
581
+ end
582
+
583
+ if null_order
584
+ literal_append(sql, Sequel.case({{oe.expression=>nil}=>null_order}, 1))
585
+ sql << ", "
586
+ end
587
+ end
588
+
630
589
  literal_append(sql, oe.expression)
631
- sql << (oe.descending ? DESC : ASC)
632
- case oe.nulls
633
- when :first
634
- sql << NULLS_FIRST
635
- when :last
636
- sql << NULLS_LAST
590
+ sql << (oe.descending ? ' DESC' : ' ASC')
591
+
592
+ unless emulate
593
+ case oe.nulls
594
+ when :first
595
+ sql << " NULLS FIRST"
596
+ when :last
597
+ sql << " NULLS LAST"
598
+ end
637
599
  end
638
600
  end
639
601
 
@@ -641,13 +603,13 @@ module Sequel
641
603
  def placeholder_literal_string_sql_append(sql, pls)
642
604
  args = pls.args
643
605
  str = pls.str
644
- sql << PAREN_OPEN if pls.parens
606
+ sql << '(' if pls.parens
645
607
  if args.is_a?(Hash)
646
608
  if args.empty?
647
609
  sql << str
648
610
  else
649
611
  re = /:(#{args.keys.map{|k| Regexp.escape(k.to_s)}.join('|')})\b/
650
- loop do
612
+ while true
651
613
  previous, q, str = str.partition(re)
652
614
  sql << previous
653
615
  literal_append(sql, args[($1||q[1..-1].to_s).to_sym]) unless q.empty?
@@ -666,19 +628,19 @@ module Sequel
666
628
  else
667
629
  i = -1
668
630
  match_len = args.length - 1
669
- loop do
670
- previous, q, str = str.partition(QUESTION_MARK)
631
+ while true
632
+ previous, q, str = str.partition('?')
671
633
  sql << previous
672
634
  literal_append(sql, args.at(i+=1)) unless q.empty?
673
635
  if str.empty?
674
636
  unless i == match_len
675
- raise Error, "Mismatched number of placeholders (#{i+1}) and placeholder arguments (#{args.length}) when using placeholder array"
637
+ raise Error, "Mismatched number of placeholders (#{i+1}) and placeholder arguments (#{args.length}) when using placeholder string"
676
638
  end
677
639
  break
678
640
  end
679
641
  end
680
642
  end
681
- sql << PAREN_CLOSE if pls.parens
643
+ sql << ')' if pls.parens
682
644
  end
683
645
 
684
646
  # Append literalization of qualified identifier to SQL string.
@@ -686,7 +648,7 @@ module Sequel
686
648
  # column/qualified. If 2 arguments are given, the 2nd should be an SQL::QualifiedIdentifier.
687
649
  def qualified_identifier_sql_append(sql, table, column=(c = table.column; table = table.table; c))
688
650
  identifier_append(sql, table)
689
- sql << DOT
651
+ sql << '.'
690
652
  identifier_append(sql, column)
691
653
  end
692
654
 
@@ -713,7 +675,7 @@ module Sequel
713
675
  schema, table = schema_and_table(table)
714
676
  if schema
715
677
  quote_identifier_append(sql, schema)
716
- sql << DOT
678
+ sql << '.'
717
679
  end
718
680
  quote_identifier_append(sql, table)
719
681
  end
@@ -723,7 +685,7 @@ module Sequel
723
685
  # should be overridden by subclasses to provide quoting not matching the
724
686
  # SQL standard, such as backtick (used by MySQL and SQLite).
725
687
  def quoted_identifier_append(sql, name)
726
- sql << QUOTE << name.to_s.gsub(QUOTE_RE, DOUBLE_QUOTE) << QUOTE
688
+ sql << '"' << name.to_s.gsub('"', '""') << '"'
727
689
  end
728
690
 
729
691
  # Split the schema information from the table, returning two strings,
@@ -753,9 +715,9 @@ module Sequel
753
715
  # Splits table_name into an array of strings.
754
716
  #
755
717
  # ds.split_qualifiers(:s) # ['s']
756
- # ds.split_qualifiers(:t__s) # ['t', 's']
757
- # ds.split_qualifiers(Sequel.qualify(:d, :t__s)) # ['d', 't', 's']
758
- # ds.split_qualifiers(Sequel.qualify(:h__d, :t__s)) # ['h', 'd', 't', 's']
718
+ # ds.split_qualifiers(Sequel[:t][:s]) # ['t', 's']
719
+ # ds.split_qualifiers(Sequel[:d][:t][:s]) # ['d', 't', 's']
720
+ # ds.split_qualifiers(Sequel.qualify(Sequel[:h][:d], Sequel[:t][:s])) # ['h', 'd', 't', 's']
759
721
  def split_qualifiers(table_name, *args)
760
722
  case table_name
761
723
  when SQL::QualifiedIdentifier
@@ -768,59 +730,116 @@ module Sequel
768
730
 
769
731
  # Append literalization of subscripts (SQL array accesses) to SQL string.
770
732
  def subscript_sql_append(sql, s)
771
- literal_append(sql, s.f)
772
- sql << BRACKET_OPEN
773
- if s.sub.length == 1 && (range = s.sub.first).is_a?(Range)
733
+ case s.expression
734
+ when Symbol, SQL::Subscript, SQL::Identifier, SQL::QualifiedIdentifier
735
+ # nothing
736
+ else
737
+ wrap_expression = true
738
+ sql << '('
739
+ end
740
+ literal_append(sql, s.expression)
741
+ if wrap_expression
742
+ sql << ')['
743
+ else
744
+ sql << '['
745
+ end
746
+ sub = s.sub
747
+ if sub.length == 1 && (range = sub.first).is_a?(Range)
774
748
  literal_append(sql, range.begin)
775
- sql << COLON
749
+ sql << ':'
776
750
  e = range.end
777
751
  e -= 1 if range.exclude_end? && e.is_a?(Integer)
778
752
  literal_append(sql, e)
779
753
  else
780
754
  expression_list_append(sql, s.sub)
781
755
  end
782
- sql << BRACKET_CLOSE
756
+ sql << ']'
783
757
  end
784
758
 
785
759
  # Append literalization of windows (for window functions) to SQL string.
786
760
  def window_sql_append(sql, opts)
787
761
  raise(Error, 'This dataset does not support window functions') unless supports_window_functions?
788
- sql << PAREN_OPEN
789
- window, part, order, frame = opts.values_at(:window, :partition, :order, :frame)
790
762
  space = false
791
- space_s = SPACE
792
- if window
763
+ space_s = ' '
764
+
765
+ sql << '('
766
+
767
+ if window = opts[:window]
793
768
  literal_append(sql, window)
794
769
  space = true
795
770
  end
796
- if part
771
+
772
+ if part = opts[:partition]
797
773
  sql << space_s if space
798
- sql << PARTITION_BY
774
+ sql << "PARTITION BY "
799
775
  expression_list_append(sql, Array(part))
800
776
  space = true
801
777
  end
802
- if order
778
+
779
+ if order = opts[:order]
803
780
  sql << space_s if space
804
- sql << ORDER_BY_NS
781
+ sql << "ORDER BY "
805
782
  expression_list_append(sql, Array(order))
806
783
  space = true
807
784
  end
808
- case frame
809
- when nil
810
- # nothing
811
- when :all
812
- sql << space_s if space
813
- sql << FRAME_ALL
814
- when :rows
815
- sql << space_s if space
816
- sql << FRAME_ROWS
817
- when String
818
- sql << space_s if space
785
+
786
+ if frame = opts[:frame]
787
+ sql << space_s if space
788
+
789
+ if frame.is_a?(String)
819
790
  sql << frame
820
791
  else
821
- raise Error, "invalid window frame clause, should be :all, :rows, a string, or nil"
792
+ case frame
793
+ when :all
794
+ frame_type = :rows
795
+ frame_start = :preceding
796
+ frame_end = :following
797
+ when :rows, :range, :groups
798
+ frame_type = frame
799
+ frame_start = :preceding
800
+ frame_end = :current
801
+ when Hash
802
+ frame_type = frame[:type]
803
+ unless frame_type == :rows || frame_type == :range || frame_type == :groups
804
+ raise Error, "invalid window :frame :type option: #{frame_type.inspect}"
805
+ end
806
+ unless frame_start = frame[:start]
807
+ raise Error, "invalid window :frame :start option: #{frame_start.inspect}"
808
+ end
809
+ frame_end = frame[:end]
810
+ frame_exclude = frame[:exclude]
811
+ else
812
+ raise Error, "invalid window :frame option: #{frame.inspect}"
813
+ end
814
+
815
+ sql << frame_type.to_s.upcase << " "
816
+ sql << 'BETWEEN ' if frame_end
817
+ window_frame_boundary_sql_append(sql, frame_start, :preceding)
818
+ if frame_end
819
+ sql << " AND "
820
+ window_frame_boundary_sql_append(sql, frame_end, :following)
821
+ end
822
+
823
+ if frame_exclude
824
+ sql << " EXCLUDE "
825
+
826
+ case frame_exclude
827
+ when :current
828
+ sql << "CURRENT ROW"
829
+ when :group
830
+ sql << "GROUP"
831
+ when :ties
832
+ sql << "TIES"
833
+ when :no_others
834
+ sql << "NO OTHERS"
835
+ else
836
+ raise Error, "invalid window :frame :exclude option: #{frame_exclude.inspect}"
837
+ end
838
+ end
839
+ end
822
840
  end
823
- sql << PAREN_CLOSE
841
+
842
+ sql << ')'
824
843
  end
825
844
 
826
845
  protected
@@ -828,7 +847,7 @@ module Sequel
828
847
  # Return a from_self dataset if an order or limit is specified, so it works as expected
829
848
  # with UNION, EXCEPT, and INTERSECT clauses.
830
849
  def compound_from_self
831
- (@opts[:sql] || @opts[:limit] || @opts[:order]) ? from_self : self
850
+ (@opts[:sql] || @opts[:limit] || @opts[:order] || @opts[:offset]) ? from_self : self
832
851
  end
833
852
 
834
853
  private
@@ -884,34 +903,43 @@ module Sequel
884
903
 
885
904
  # Append aliasing expression to SQL string.
886
905
  def as_sql_append(sql, aliaz, column_aliases=nil)
887
- sql << AS
906
+ sql << ' AS '
888
907
  quote_identifier_append(sql, aliaz)
889
908
  if column_aliases
890
909
  raise Error, "#{db.database_type} does not support derived column lists" unless supports_derived_column_lists?
891
- sql << PAREN_OPEN
910
+ sql << '('
892
911
  identifier_list_append(sql, column_aliases)
893
- sql << PAREN_CLOSE
912
+ sql << ')'
894
913
  end
895
914
  end
896
915
 
897
- # Raise an InvalidOperation exception if deletion is not allowed
898
- # for this dataset
916
+ # Don't allow caching SQL if specifically marked not to.
917
+ def cache_sql?
918
+ !@opts[:no_cache_sql] && !cache_get(:_no_cache_sql)
919
+ end
920
+
921
+ # Raise an InvalidOperation exception if deletion is not allowed for this dataset.
899
922
  def check_modification_allowed!
900
923
  raise(InvalidOperation, "Grouped datasets cannot be modified") if opts[:group]
901
924
  raise(InvalidOperation, "Joined datasets cannot be modified") if !supports_modifying_joins? && joined_dataset?
902
925
  end
903
926
 
927
+ # Raise error if the dataset uses limits or offsets.
928
+ def check_not_limited!(type)
929
+ return if @opts[:skip_limit_check] && type != :truncate
930
+ raise InvalidOperation, "Dataset##{type} not supported on datasets with limits or offsets" if opts[:limit] || opts[:offset]
931
+ end
932
+
904
933
  # Alias of check_modification_allowed!
905
934
  def check_truncation_allowed!
906
935
  check_modification_allowed!
907
936
  end
908
937
 
909
938
  # Append column list to SQL string.
910
- # Converts an array of column names into a comma seperated string of
911
- # column names. If the array is empty, a wildcard (*) is returned.
939
+ # If the column list is empty, a wildcard (*) is appended.
912
940
  def column_list_append(sql, columns)
913
941
  if (columns.nil? || columns.empty?)
914
- sql << WILDCARD
942
+ sql << '*'
915
943
  else
916
944
  expression_list_append(sql, columns)
917
945
  end
@@ -924,9 +952,9 @@ module Sequel
924
952
  def complex_expression_arg_pairs(args)
925
953
  case args.length
926
954
  when 1
927
- args.at(0)
955
+ args[0]
928
956
  when 2
929
- yield args.at(0), args.at(1)
957
+ yield args[0], args[1]
930
958
  else
931
959
  args.inject{|m, a| yield(m, a)}
932
960
  end
@@ -954,9 +982,9 @@ module Sequel
954
982
  f = BITWISE_METHOD_MAP[op]
955
983
  complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.function(f, a, b)}
956
984
  when :'B~'
957
- sql << BITCOMP_OPEN
958
- literal_append(sql, args.at(0))
959
- sql << BITCOMP_CLOSE
985
+ sql << "((0 - "
986
+ literal_append(sql, args[0])
987
+ sql << ") - 1)"
960
988
  end
961
989
  end
962
990
 
@@ -967,25 +995,30 @@ module Sequel
967
995
 
968
996
  # The alias to use for datasets, takes a number to make sure the name is unique.
969
997
  def dataset_alias(number)
970
- :"#{DATASET_ALIAS_BASE_NAME}#{number}"
998
+ :"t#{number}"
971
999
  end
972
1000
 
973
1001
  # The strftime format to use when literalizing the time.
974
1002
  def default_timestamp_format
975
- requires_sql_standard_datetimes? ? STANDARD_TIMESTAMP_FORMAT : TIMESTAMP_FORMAT
1003
+ requires_sql_standard_datetimes? ? "TIMESTAMP '%Y-%m-%d %H:%M:%S%N%z'" : "'%Y-%m-%d %H:%M:%S%N%z'"
976
1004
  end
977
1005
 
978
1006
  def delete_delete_sql(sql)
979
- sql << DELETE
1007
+ sql << 'DELETE'
980
1008
  end
981
1009
 
982
1010
  def delete_from_sql(sql)
983
1011
  if f = @opts[:from]
984
- sql << FROM
1012
+ sql << ' FROM '
985
1013
  source_list_append(sql, f)
986
1014
  end
987
1015
  end
988
1016
 
1017
+ # Disable caching of SQL for the current dataset
1018
+ def disable_sql_caching!
1019
+ cache_set(:_no_cache_sql, true)
1020
+ end
1021
+
989
1022
  # An SQL FROM clause to use in SELECT statements where the dataset has
990
1023
  # no from tables.
991
1024
  def empty_from_sql
@@ -998,10 +1031,11 @@ module Sequel
998
1031
  false
999
1032
  end
1000
1033
 
1001
- # Append literalization of array of expressions to SQL string.
1034
+ # Append literalization of array of expressions to SQL string, separating them
1035
+ # with commas.
1002
1036
  def expression_list_append(sql, columns)
1003
1037
  c = false
1004
- co = COMMA
1038
+ co = ', '
1005
1039
  columns.each do |col|
1006
1040
  sql << co if c
1007
1041
  literal_append(sql, col)
@@ -1009,14 +1043,14 @@ module Sequel
1009
1043
  end
1010
1044
  end
1011
1045
 
1012
- # Append literalization of array of grouping elements to SQL string.
1046
+ # Append literalization of array of grouping elements to SQL string, seperating them with commas.
1013
1047
  def grouping_element_list_append(sql, columns)
1014
1048
  c = false
1015
- co = COMMA
1049
+ co = ', '
1016
1050
  columns.each do |col|
1017
1051
  sql << co if c
1018
1052
  if col.is_a?(Array) && col.empty?
1019
- sql << EMPTY_PARENS
1053
+ sql << '()'
1020
1054
  else
1021
1055
  literal_append(sql, Array(col))
1022
1056
  end
@@ -1035,9 +1069,12 @@ module Sequel
1035
1069
  # of hours and minutes.
1036
1070
  def format_timestamp(v)
1037
1071
  v2 = db.from_application_timestamp(v)
1038
- fmt = default_timestamp_format.gsub(FORMAT_TIMESTAMP_RE) do |m|
1039
- if m == FORMAT_USEC
1040
- format_timestamp_usec(v.is_a?(DateTime) ? v.sec_fraction*(DATETIME_SECFRACTION_ARG) : v.usec) if supports_timestamp_usecs?
1072
+ fmt = default_timestamp_format.gsub(/%[Nz]/) do |m|
1073
+ if m == '%N'
1074
+ # Ruby 1.9 supports %N in timestamp formats, but Sequel has supported %N
1075
+ # for longer in a different way, where the . is already appended and only 6
1076
+ # decimal places are used by default.
1077
+ format_timestamp_usec(v.is_a?(DateTime) ? v.sec_fraction*(1000000) : v.usec) if supports_timestamp_usecs?
1041
1078
  else
1042
1079
  if supports_timestamp_timezones?
1043
1080
  # Would like to just use %z format, but it doesn't appear to work on Windows
@@ -1052,13 +1089,13 @@ module Sequel
1052
1089
 
1053
1090
  # Return the SQL timestamp fragment to use for the timezone offset.
1054
1091
  def format_timestamp_offset(hour, minute)
1055
- sprintf(FORMAT_OFFSET, hour, minute)
1092
+ sprintf("%+03i%02i", hour, minute)
1056
1093
  end
1057
1094
 
1058
1095
  # Return the SQL timestamp fragment to use for the fractional time part.
1059
1096
  # Should start with the decimal point. Uses 6 decimal places by default.
1060
- def format_timestamp_usec(usec)
1061
- unless (ts = timestamp_precision) == 6
1097
+ def format_timestamp_usec(usec, ts=timestamp_precision)
1098
+ unless ts == 6
1062
1099
  usec = usec/(10 ** (6 - ts))
1063
1100
  end
1064
1101
  sprintf(".%0#{ts}d", usec)
@@ -1084,7 +1121,7 @@ module Sequel
1084
1121
  # Append literalization of array of identifiers to SQL string.
1085
1122
  def identifier_list_append(sql, args)
1086
1123
  c = false
1087
- comma = COMMA
1124
+ comma = ', '
1088
1125
  args.each do |a|
1089
1126
  sql << comma if c
1090
1127
  identifier_append(sql, a)
@@ -1092,14 +1129,13 @@ module Sequel
1092
1129
  end
1093
1130
  end
1094
1131
 
1095
- # Modify the identifier returned from the database based on the
1096
- # identifier_output_method.
1132
+ # Upcase identifiers by default when inputting them into the database.
1097
1133
  def input_identifier(v)
1098
- (i = identifier_input_method) ? v.to_s.send(i) : v.to_s
1134
+ v.to_s.upcase
1099
1135
  end
1100
1136
 
1101
1137
  def insert_into_sql(sql)
1102
- sql << INTO
1138
+ sql << " INTO "
1103
1139
  if (f = @opts[:from]) && f.length == 1
1104
1140
  identifier_append(sql, unaliased_identifier(f.first))
1105
1141
  else
@@ -1110,30 +1146,36 @@ module Sequel
1110
1146
  def insert_columns_sql(sql)
1111
1147
  columns = opts[:columns]
1112
1148
  if columns && !columns.empty?
1113
- sql << PAREN_SPACE_OPEN
1149
+ sql << ' ('
1114
1150
  identifier_list_append(sql, columns)
1115
- sql << PAREN_CLOSE
1151
+ sql << ')'
1116
1152
  end
1117
1153
  end
1118
1154
 
1155
+ # The columns and values to use for an empty insert if the database doesn't support
1156
+ # INSERT with DEFAULT VALUES.
1157
+ def insert_empty_columns_values
1158
+ [[columns.last], [DEFAULT]]
1159
+ end
1160
+
1119
1161
  def insert_insert_sql(sql)
1120
- sql << INSERT
1162
+ sql << "INSERT"
1121
1163
  end
1122
1164
 
1123
1165
  def insert_values_sql(sql)
1124
1166
  case values = opts[:values]
1125
1167
  when Array
1126
1168
  if values.empty?
1127
- sql << DEFAULT_VALUES
1169
+ sql << " DEFAULT VALUES"
1128
1170
  else
1129
- sql << VALUES
1171
+ sql << " VALUES "
1130
1172
  literal_append(sql, values)
1131
1173
  end
1132
1174
  when Dataset
1133
- sql << SPACE
1175
+ sql << ' '
1134
1176
  subselect_sql_append(sql, values)
1135
1177
  when LiteralString
1136
- sql << SPACE << values
1178
+ sql << ' ' << values
1137
1179
  else
1138
1180
  raise Error, "Unsupported INSERT values type, should be an Array or Dataset: #{values.inspect}"
1139
1181
  end
@@ -1141,7 +1183,7 @@ module Sequel
1141
1183
 
1142
1184
  def insert_returning_sql(sql)
1143
1185
  if opts.has_key?(:returning)
1144
- sql << RETURNING
1186
+ sql << " RETURNING "
1145
1187
  column_list_append(sql, Array(opts[:returning]))
1146
1188
  end
1147
1189
  end
@@ -1151,7 +1193,7 @@ module Sequel
1151
1193
  # SQL fragment specifying a JOIN type, converts underscores to
1152
1194
  # spaces and upcases.
1153
1195
  def join_type_sql(join_type)
1154
- "#{join_type.to_s.gsub(UNDERSCORE, SPACE).upcase} JOIN"
1196
+ "#{join_type.to_s.gsub('_', ' ').upcase} JOIN"
1155
1197
  end
1156
1198
 
1157
1199
  # Append a literalization of the array to SQL string.
@@ -1177,18 +1219,18 @@ module Sequel
1177
1219
 
1178
1220
  # Append literalization of dataset to SQL string. Does a subselect inside parantheses.
1179
1221
  def literal_dataset_append(sql, v)
1180
- sql << LATERAL if v.opts[:lateral]
1181
- sql << PAREN_OPEN
1222
+ sql << 'LATERAL ' if v.opts[:lateral]
1223
+ sql << '('
1182
1224
  subselect_sql_append(sql, v)
1183
- sql << PAREN_CLOSE
1225
+ sql << ')'
1184
1226
  end
1185
1227
 
1186
1228
  # SQL fragment for Date, using the ISO8601 format.
1187
1229
  def literal_date(v)
1188
1230
  if requires_sql_standard_datetimes?
1189
- v.strftime(FORMAT_DATE_STANDARD)
1231
+ v.strftime("DATE '%Y-%m-%d'")
1190
1232
  else
1191
- v.strftime(FORMAT_DATE)
1233
+ v.strftime("'%Y-%m-%d'")
1192
1234
  end
1193
1235
  end
1194
1236
 
@@ -1209,7 +1251,7 @@ module Sequel
1209
1251
 
1210
1252
  # SQL fragment for false
1211
1253
  def literal_false
1212
- BOOL_FALSE
1254
+ "'f'"
1213
1255
  end
1214
1256
 
1215
1257
  # SQL fragment for Float
@@ -1229,7 +1271,7 @@ module Sequel
1229
1271
 
1230
1272
  # SQL fragment for nil
1231
1273
  def literal_nil
1232
- NULL
1274
+ "NULL"
1233
1275
  end
1234
1276
 
1235
1277
  # Append a literalization of the object to the given SQL string.
@@ -1237,6 +1279,10 @@ module Sequel
1237
1279
  # calls +sql_literal+ if object responds to it, otherwise raises an error.
1238
1280
  # If a database specific type is allowed, this should be overriden in a subclass.
1239
1281
  def literal_other_append(sql, v)
1282
+ # We can't be sure if v will always literalize to the same SQL, so
1283
+ # don't cache SQL for a dataset that uses this.
1284
+ disable_sql_caching!
1285
+
1240
1286
  if v.respond_to?(:sql_literal_append)
1241
1287
  v.sql_literal_append(self, sql)
1242
1288
  elsif v.respond_to?(:sql_literal)
@@ -1248,7 +1294,7 @@ module Sequel
1248
1294
 
1249
1295
  # SQL fragment for Sequel::SQLTime, containing just the time part
1250
1296
  def literal_sqltime(v)
1251
- v.strftime("'%H:%M:%S#{format_timestamp_usec(v.usec) if supports_timestamp_usecs?}'")
1297
+ v.strftime("'%H:%M:%S#{format_timestamp_usec(v.usec, sqltime_precision) if supports_timestamp_usecs?}'")
1252
1298
  end
1253
1299
 
1254
1300
  # Append literalization of Sequel::SQLTime to SQL string.
@@ -1258,7 +1304,7 @@ module Sequel
1258
1304
 
1259
1305
  # Append literalization of string to SQL string.
1260
1306
  def literal_string_append(sql, v)
1261
- sql << APOS << v.gsub(APOS_RE, DOUBLE_APOS) << APOS
1307
+ sql << "'" << v.gsub("'", "''") << "'"
1262
1308
  end
1263
1309
 
1264
1310
  # Append literalization of symbol to SQL string.
@@ -1266,7 +1312,7 @@ module Sequel
1266
1312
  c_table, column, c_alias = split_symbol(v)
1267
1313
  if c_table
1268
1314
  quote_identifier_append(sql, c_table)
1269
- sql << DOT
1315
+ sql << '.'
1270
1316
  end
1271
1317
  quote_identifier_append(sql, column)
1272
1318
  as_sql_append(sql, c_alias) if c_alias
@@ -1284,7 +1330,7 @@ module Sequel
1284
1330
 
1285
1331
  # SQL fragment for true
1286
1332
  def literal_true
1287
- BOOL_TRUE
1333
+ "'t'"
1288
1334
  end
1289
1335
 
1290
1336
  # What strategy to use for import/multi_insert. While SQL-92 defaults
@@ -1295,9 +1341,10 @@ module Sequel
1295
1341
  :separate
1296
1342
  end
1297
1343
 
1344
+
1298
1345
  # Get the native function name given the emulated function name.
1299
1346
  def native_function_name(emulated_function)
1300
- self.class.const_get(:EMULATED_FUNCTION_MAP).fetch(emulated_function, emulated_function)
1347
+ emulated_function
1301
1348
  end
1302
1349
 
1303
1350
  # Returns a qualified column name (including a table name) if the column
@@ -1321,43 +1368,43 @@ module Sequel
1321
1368
  end
1322
1369
  end
1323
1370
 
1324
- # Qualify the given expression e to the given table.
1371
+ # Qualify the given expression to the given table.
1325
1372
  def qualified_expression(e, table)
1326
- Qualifier.new(self, table).transform(e)
1373
+ Qualifier.new(table).transform(e)
1327
1374
  end
1328
1375
 
1329
1376
  def select_columns_sql(sql)
1330
- sql << SPACE
1377
+ sql << ' '
1331
1378
  column_list_append(sql, @opts[:select])
1332
1379
  end
1333
1380
 
1334
1381
  def select_distinct_sql(sql)
1335
1382
  if distinct = @opts[:distinct]
1336
- sql << DISTINCT
1383
+ sql << " DISTINCT"
1337
1384
  unless distinct.empty?
1338
- sql << ON_PAREN
1385
+ sql << " ON ("
1339
1386
  expression_list_append(sql, distinct)
1340
- sql << PAREN_CLOSE
1387
+ sql << ')'
1341
1388
  end
1342
1389
  end
1343
1390
  end
1344
1391
 
1345
1392
  # Modify the sql to add a dataset to the via an EXCEPT, INTERSECT, or UNION clause.
1346
1393
  # This uses a subselect for the compound datasets used, because using parantheses doesn't
1347
- # work on all databases. I consider this an ugly hack, but can't I think of a better default.
1394
+ # work on all databases.
1348
1395
  def select_compounds_sql(sql)
1349
1396
  return unless c = @opts[:compounds]
1350
1397
  c.each do |type, dataset, all|
1351
- sql << SPACE << type.to_s.upcase
1352
- sql << ALL if all
1353
- sql << SPACE
1398
+ sql << ' ' << type.to_s.upcase
1399
+ sql << ' ALL' if all
1400
+ sql << ' '
1354
1401
  compound_dataset_sql_append(sql, dataset)
1355
1402
  end
1356
1403
  end
1357
1404
 
1358
1405
  def select_from_sql(sql)
1359
1406
  if f = @opts[:from]
1360
- sql << FROM
1407
+ sql << ' FROM '
1361
1408
  source_list_append(sql, f)
1362
1409
  elsif f = empty_from_sql
1363
1410
  sql << f
@@ -1366,19 +1413,19 @@ module Sequel
1366
1413
 
1367
1414
  def select_group_sql(sql)
1368
1415
  if group = @opts[:group]
1369
- sql << GROUP_BY
1416
+ sql << " GROUP BY "
1370
1417
  if go = @opts[:group_options]
1371
1418
  if go == :"grouping sets"
1372
- sql << go.to_s.upcase << PAREN_OPEN
1419
+ sql << go.to_s.upcase << '('
1373
1420
  grouping_element_list_append(sql, group)
1374
- sql << PAREN_CLOSE
1421
+ sql << ')'
1375
1422
  elsif uses_with_rollup?
1376
1423
  expression_list_append(sql, group)
1377
- sql << SPACE_WITH << go.to_s.upcase
1424
+ sql << " WITH " << go.to_s.upcase
1378
1425
  else
1379
- sql << go.to_s.upcase << PAREN_OPEN
1426
+ sql << go.to_s.upcase << '('
1380
1427
  expression_list_append(sql, group)
1381
- sql << PAREN_CLOSE
1428
+ sql << ')'
1382
1429
  end
1383
1430
  else
1384
1431
  expression_list_append(sql, group)
@@ -1388,7 +1435,7 @@ module Sequel
1388
1435
 
1389
1436
  def select_having_sql(sql)
1390
1437
  if having = @opts[:having]
1391
- sql << HAVING
1438
+ sql << " HAVING "
1392
1439
  literal_append(sql, having)
1393
1440
  end
1394
1441
  end
@@ -1401,10 +1448,10 @@ module Sequel
1401
1448
 
1402
1449
  def select_limit_sql(sql)
1403
1450
  if l = @opts[:limit]
1404
- sql << LIMIT
1451
+ sql << " LIMIT "
1405
1452
  literal_append(sql, l)
1406
1453
  if o = @opts[:offset]
1407
- sql << OFFSET
1454
+ sql << " OFFSET "
1408
1455
  literal_append(sql, o)
1409
1456
  end
1410
1457
  elsif @opts[:offset]
@@ -1415,9 +1462,9 @@ module Sequel
1415
1462
  def select_lock_sql(sql)
1416
1463
  case l = @opts[:lock]
1417
1464
  when :update
1418
- sql << FOR_UPDATE
1465
+ sql << ' FOR UPDATE'
1419
1466
  when String
1420
- sql << SPACE << l
1467
+ sql << ' ' << l
1421
1468
  end
1422
1469
  end
1423
1470
 
@@ -1425,13 +1472,13 @@ module Sequel
1425
1472
  # in the adapter, as many databases do not support just a plain offset with
1426
1473
  # no limit.
1427
1474
  def select_only_offset_sql(sql)
1428
- sql << OFFSET
1475
+ sql << " OFFSET "
1429
1476
  literal_append(sql, @opts[:offset])
1430
1477
  end
1431
1478
 
1432
1479
  def select_order_sql(sql)
1433
1480
  if o = @opts[:order]
1434
- sql << ORDER_BY
1481
+ sql << " ORDER BY "
1435
1482
  expression_list_append(sql, o)
1436
1483
  end
1437
1484
  end
@@ -1439,56 +1486,70 @@ module Sequel
1439
1486
  alias update_order_sql select_order_sql
1440
1487
 
1441
1488
  def select_select_sql(sql)
1442
- sql << SELECT
1489
+ sql << 'SELECT'
1443
1490
  end
1444
1491
 
1445
1492
  def select_where_sql(sql)
1446
1493
  if w = @opts[:where]
1447
- sql << WHERE
1494
+ sql << " WHERE "
1448
1495
  literal_append(sql, w)
1449
1496
  end
1450
1497
  end
1451
1498
  alias delete_where_sql select_where_sql
1452
1499
  alias update_where_sql select_where_sql
1453
1500
 
1501
+ def select_window_sql(sql)
1502
+ if ws = @opts[:window]
1503
+ sql << " WINDOW "
1504
+ c = false
1505
+ co = ', '
1506
+ as = ' AS '
1507
+ ws.map do |name, window|
1508
+ sql << co if c
1509
+ literal_append(sql, name)
1510
+ sql << as
1511
+ literal_append(sql, window)
1512
+ c ||= true
1513
+ end
1514
+ end
1515
+ end
1516
+
1454
1517
  def select_with_sql(sql)
1455
1518
  return unless supports_cte?
1456
1519
  ws = opts[:with]
1457
1520
  return if !ws || ws.empty?
1458
1521
  sql << select_with_sql_base
1459
1522
  c = false
1460
- comma = COMMA
1523
+ comma = ', '
1461
1524
  ws.each do |w|
1462
1525
  sql << comma if c
1463
- quote_identifier_append(sql, w[:name])
1464
- if args = w[:args]
1465
- sql << PAREN_OPEN
1466
- identifier_list_append(sql, args)
1467
- sql << PAREN_CLOSE
1468
- end
1469
- sql << AS
1526
+ select_with_sql_prefix(sql, w)
1470
1527
  literal_dataset_append(sql, w[:dataset])
1471
1528
  c ||= true
1472
1529
  end
1473
- sql << SPACE
1530
+ sql << ' '
1474
1531
  end
1475
1532
  alias delete_with_sql select_with_sql
1476
1533
  alias insert_with_sql select_with_sql
1477
1534
  alias update_with_sql select_with_sql
1478
1535
 
1479
- # The base keyword to use for the SQL WITH clause
1480
1536
  def select_with_sql_base
1481
- SQL_WITH
1537
+ "WITH "
1482
1538
  end
1483
1539
 
1484
- # Whether the symbol cache should be skipped when literalizing the dataset
1485
- def skip_symbol_cache?
1486
- @skip_symbol_cache
1540
+ def select_with_sql_prefix(sql, w)
1541
+ quote_identifier_append(sql, w[:name])
1542
+ if args = w[:args]
1543
+ sql << '('
1544
+ identifier_list_append(sql, args)
1545
+ sql << ')'
1546
+ end
1547
+ sql << ' AS '
1487
1548
  end
1488
1549
 
1489
- # Set the dataset to skip the symbol cache
1490
- def skip_symbol_cache!
1491
- @skip_symbol_cache = true
1550
+ # Whether the symbol cache should be skipped when literalizing the dataset
1551
+ def skip_symbol_cache?
1552
+ @opts[:skip_symbol_cache]
1492
1553
  end
1493
1554
 
1494
1555
  # Append literalization of array of sources/tables to SQL string, raising an Error if there
@@ -1504,11 +1565,17 @@ module Sequel
1504
1565
  end
1505
1566
 
1506
1567
  # The string that is appended to to create the SQL query, the empty
1507
- # string by default
1568
+ # string by default.
1508
1569
  def sql_string_origin
1509
- ''
1570
+ String.new
1510
1571
  end
1511
1572
 
1573
+ # The precision to use for SQLTime instances (time column values without dates).
1574
+ # Defaults to timestamp_precision.
1575
+ def sqltime_precision
1576
+ timestamp_precision
1577
+ end
1578
+
1512
1579
  # SQL to use if this dataset uses static SQL. Since static SQL
1513
1580
  # can be a PlaceholderLiteralString in addition to a String,
1514
1581
  # we literalize nonstrings. If there is an append_sql for this
@@ -1529,9 +1596,19 @@ module Sequel
1529
1596
  end
1530
1597
  end
1531
1598
 
1532
- # Append literalization of the subselect to SQL String.
1599
+ # Append literalization of the subselect to SQL string.
1533
1600
  def subselect_sql_append(sql, ds)
1534
- ds.clone(:append_sql=>sql).sql
1601
+ sds = subselect_sql_dataset(sql, ds)
1602
+ sds.sql
1603
+ unless sds.send(:cache_sql?)
1604
+ # If subquery dataset does not allow caching SQL,
1605
+ # then this dataset should not allow caching SQL.
1606
+ disable_sql_caching!
1607
+ end
1608
+ end
1609
+
1610
+ def subselect_sql_dataset(sql, ds)
1611
+ ds.clone(:append_sql=>sql)
1535
1612
  end
1536
1613
 
1537
1614
  # The number of decimal digits of precision to use in timestamps.
@@ -1540,13 +1617,13 @@ module Sequel
1540
1617
  end
1541
1618
 
1542
1619
  def update_table_sql(sql)
1543
- sql << SPACE
1620
+ sql << ' '
1544
1621
  source_list_append(sql, @opts[:from])
1545
1622
  select_join_sql(sql) if supports_modifying_joins?
1546
1623
  end
1547
1624
 
1548
1625
  def update_set_sql(sql)
1549
- sql << SET
1626
+ sql << ' SET '
1550
1627
  values = @opts[:values]
1551
1628
  if values.is_a?(Hash)
1552
1629
  update_sql_values_hash(sql, values)
@@ -1557,9 +1634,9 @@ module Sequel
1557
1634
 
1558
1635
  def update_sql_values_hash(sql, values)
1559
1636
  c = false
1560
- eq = EQUAL
1637
+ eq = ' = '
1561
1638
  values.each do |k, v|
1562
- sql << COMMA if c
1639
+ sql << ', ' if c
1563
1640
  if k.is_a?(String) && !k.is_a?(LiteralString)
1564
1641
  quote_identifier_append(sql, k)
1565
1642
  else
@@ -1572,7 +1649,37 @@ module Sequel
1572
1649
  end
1573
1650
 
1574
1651
  def update_update_sql(sql)
1575
- sql << UPDATE
1652
+ sql << 'UPDATE'
1653
+ end
1654
+
1655
+ def window_frame_boundary_sql_append(sql, boundary, direction)
1656
+ case boundary
1657
+ when :current
1658
+ sql << "CURRENT ROW"
1659
+ when :preceding
1660
+ sql << "UNBOUNDED PRECEDING"
1661
+ when :following
1662
+ sql << "UNBOUNDED FOLLOWING"
1663
+ else
1664
+ if boundary.is_a?(Array)
1665
+ offset, direction = boundary
1666
+ unless boundary.length == 2 && (direction == :preceding || direction == :following)
1667
+ raise Error, "invalid window :frame boundary (:start or :end) option: #{boundary.inspect}"
1668
+ end
1669
+ else
1670
+ offset = boundary
1671
+ end
1672
+
1673
+ case offset
1674
+ when Numeric, String, SQL::Cast
1675
+ # nothing
1676
+ else
1677
+ raise Error, "invalid window :frame boundary (:start or :end) option: #{boundary.inspect}"
1678
+ end
1679
+
1680
+ literal_append(sql, offset)
1681
+ sql << (direction == :preceding ? " PRECEDING" : " FOLLOWING")
1682
+ end
1576
1683
  end
1577
1684
  end
1578
1685
  end