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.
- checksums.yaml +5 -5
- data/CHANGELOG +405 -5656
- data/MIT-LICENSE +1 -1
- data/README.rdoc +232 -157
- data/bin/sequel +32 -9
- data/doc/advanced_associations.rdoc +252 -188
- data/doc/association_basics.rdoc +231 -273
- data/doc/bin_sequel.rdoc +5 -3
- data/doc/cheat_sheet.rdoc +75 -48
- data/doc/code_order.rdoc +28 -10
- data/doc/core_extensions.rdoc +104 -63
- data/doc/dataset_basics.rdoc +12 -21
- data/doc/dataset_filtering.rdoc +99 -86
- data/doc/extensions.rdoc +3 -10
- data/doc/mass_assignment.rdoc +74 -31
- data/doc/migration.rdoc +72 -46
- data/doc/model_dataset_method_design.rdoc +129 -0
- data/doc/model_hooks.rdoc +15 -25
- data/doc/model_plugins.rdoc +12 -12
- data/doc/mssql_stored_procedures.rdoc +3 -3
- data/doc/object_model.rdoc +59 -69
- data/doc/opening_databases.rdoc +84 -94
- data/doc/postgresql.rdoc +268 -38
- data/doc/prepared_statements.rdoc +29 -24
- data/doc/querying.rdoc +184 -164
- data/doc/reflection.rdoc +5 -6
- data/doc/release_notes/5.0.0.txt +159 -0
- data/doc/release_notes/5.1.0.txt +31 -0
- data/doc/release_notes/5.10.0.txt +84 -0
- data/doc/release_notes/5.11.0.txt +83 -0
- data/doc/release_notes/5.12.0.txt +141 -0
- data/doc/release_notes/5.13.0.txt +27 -0
- data/doc/release_notes/5.14.0.txt +63 -0
- data/doc/release_notes/5.15.0.txt +39 -0
- data/doc/release_notes/5.16.0.txt +110 -0
- data/doc/release_notes/5.17.0.txt +31 -0
- data/doc/release_notes/5.18.0.txt +69 -0
- data/doc/release_notes/5.19.0.txt +28 -0
- data/doc/release_notes/5.2.0.txt +33 -0
- data/doc/release_notes/5.20.0.txt +89 -0
- data/doc/release_notes/5.21.0.txt +87 -0
- data/doc/release_notes/5.22.0.txt +48 -0
- data/doc/release_notes/5.23.0.txt +56 -0
- data/doc/release_notes/5.24.0.txt +56 -0
- data/doc/release_notes/5.25.0.txt +32 -0
- data/doc/release_notes/5.26.0.txt +35 -0
- data/doc/release_notes/5.27.0.txt +21 -0
- data/doc/release_notes/5.28.0.txt +16 -0
- data/doc/release_notes/5.29.0.txt +22 -0
- data/doc/release_notes/5.3.0.txt +121 -0
- data/doc/release_notes/5.30.0.txt +20 -0
- data/doc/release_notes/5.31.0.txt +148 -0
- data/doc/release_notes/5.32.0.txt +46 -0
- data/doc/release_notes/5.33.0.txt +24 -0
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.4.0.txt +80 -0
- data/doc/release_notes/5.5.0.txt +61 -0
- data/doc/release_notes/5.6.0.txt +31 -0
- data/doc/release_notes/5.7.0.txt +108 -0
- data/doc/release_notes/5.8.0.txt +170 -0
- data/doc/release_notes/5.9.0.txt +99 -0
- data/doc/schema_modification.rdoc +102 -77
- data/doc/security.rdoc +160 -87
- data/doc/sharding.rdoc +74 -47
- data/doc/sql.rdoc +135 -122
- data/doc/testing.rdoc +34 -18
- data/doc/thread_safety.rdoc +2 -4
- data/doc/transactions.rdoc +101 -19
- data/doc/validations.rdoc +64 -51
- data/doc/virtual_rows.rdoc +90 -109
- data/lib/sequel.rb +3 -1
- data/lib/sequel/adapters/ado.rb +154 -22
- data/lib/sequel/adapters/ado/access.rb +21 -21
- data/lib/sequel/adapters/ado/mssql.rb +8 -15
- data/lib/sequel/adapters/amalgalite.rb +17 -25
- data/lib/sequel/adapters/ibmdb.rb +52 -58
- data/lib/sequel/adapters/jdbc.rb +149 -127
- data/lib/sequel/adapters/jdbc/db2.rb +32 -40
- data/lib/sequel/adapters/jdbc/derby.rb +56 -58
- data/lib/sequel/adapters/jdbc/h2.rb +40 -30
- data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
- data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
- data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
- data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
- data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
- data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
- data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
- data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
- data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
- data/lib/sequel/adapters/mock.rb +104 -113
- data/lib/sequel/adapters/mysql.rb +42 -61
- data/lib/sequel/adapters/mysql2.rb +126 -35
- data/lib/sequel/adapters/odbc.rb +21 -28
- data/lib/sequel/adapters/odbc/db2.rb +3 -1
- data/lib/sequel/adapters/odbc/mssql.rb +11 -15
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/oracle.rb +62 -68
- data/lib/sequel/adapters/postgres.rb +257 -311
- data/lib/sequel/adapters/postgresql.rb +3 -1
- data/lib/sequel/adapters/shared/access.rb +75 -79
- data/lib/sequel/adapters/shared/db2.rb +96 -74
- data/lib/sequel/adapters/shared/mssql.rb +258 -213
- data/lib/sequel/adapters/shared/mysql.rb +284 -216
- data/lib/sequel/adapters/shared/oracle.rb +175 -60
- data/lib/sequel/adapters/shared/postgres.rb +829 -383
- data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
- data/lib/sequel/adapters/shared/sqlite.rb +382 -159
- data/lib/sequel/adapters/sqlanywhere.rb +53 -38
- data/lib/sequel/adapters/sqlite.rb +111 -105
- data/lib/sequel/adapters/tinytds.rb +38 -46
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
- data/lib/sequel/adapters/utils/replace.rb +3 -4
- data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
- data/lib/sequel/ast_transformer.rb +13 -89
- data/lib/sequel/connection_pool.rb +54 -26
- data/lib/sequel/connection_pool/sharded_single.rb +19 -12
- data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
- data/lib/sequel/connection_pool/single.rb +21 -12
- data/lib/sequel/connection_pool/threaded.rb +137 -119
- data/lib/sequel/core.rb +352 -320
- data/lib/sequel/database.rb +19 -2
- data/lib/sequel/database/connecting.rb +70 -55
- data/lib/sequel/database/dataset.rb +15 -5
- data/lib/sequel/database/dataset_defaults.rb +20 -102
- data/lib/sequel/database/features.rb +20 -4
- data/lib/sequel/database/logging.rb +25 -7
- data/lib/sequel/database/misc.rb +132 -118
- data/lib/sequel/database/query.rb +51 -28
- data/lib/sequel/database/schema_generator.rb +188 -75
- data/lib/sequel/database/schema_methods.rb +161 -92
- data/lib/sequel/database/transactions.rb +260 -58
- data/lib/sequel/dataset.rb +28 -12
- data/lib/sequel/dataset/actions.rb +354 -170
- data/lib/sequel/dataset/dataset_module.rb +46 -0
- data/lib/sequel/dataset/features.rb +81 -34
- data/lib/sequel/dataset/graph.rb +82 -58
- data/lib/sequel/dataset/misc.rb +139 -47
- data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
- data/lib/sequel/dataset/prepared_statements.rb +188 -85
- data/lib/sequel/dataset/query.rb +428 -214
- data/lib/sequel/dataset/sql.rb +446 -339
- data/lib/sequel/deprecated.rb +14 -2
- data/lib/sequel/exceptions.rb +48 -16
- data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
- data/lib/sequel/extensions/_model_pg_row.rb +43 -0
- data/lib/sequel/extensions/_pretty_table.rb +10 -9
- data/lib/sequel/extensions/any_not_empty.rb +45 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/blank.rb +2 -0
- data/lib/sequel/extensions/caller_logging.rb +79 -0
- data/lib/sequel/extensions/columns_introspection.rb +9 -4
- data/lib/sequel/extensions/connection_expiration.rb +99 -0
- data/lib/sequel/extensions/connection_validator.rb +26 -13
- data/lib/sequel/extensions/constant_sql_override.rb +65 -0
- data/lib/sequel/extensions/constraint_validations.rb +93 -38
- data/lib/sequel/extensions/core_extensions.rb +45 -53
- data/lib/sequel/extensions/core_refinements.rb +44 -46
- data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
- data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
- data/lib/sequel/extensions/date_arithmetic.rb +42 -16
- data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
- data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
- data/lib/sequel/extensions/error_sql.rb +7 -3
- data/lib/sequel/extensions/escaped_like.rb +100 -0
- data/lib/sequel/extensions/eval_inspect.rb +14 -15
- data/lib/sequel/extensions/exclude_or_null.rb +68 -0
- data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
- data/lib/sequel/extensions/freeze_datasets.rb +3 -0
- data/lib/sequel/extensions/from_block.rb +2 -31
- data/lib/sequel/extensions/graph_each.rb +19 -6
- data/lib/sequel/extensions/identifier_mangling.rb +180 -0
- data/lib/sequel/extensions/implicit_subquery.rb +48 -0
- data/lib/sequel/extensions/index_caching.rb +109 -0
- data/lib/sequel/extensions/inflector.rb +8 -4
- data/lib/sequel/extensions/integer64.rb +32 -0
- data/lib/sequel/extensions/looser_typecasting.rb +19 -9
- data/lib/sequel/extensions/migration.rb +132 -80
- data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
- data/lib/sequel/extensions/named_timezones.rb +88 -23
- data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
- data/lib/sequel/extensions/null_dataset.rb +12 -8
- data/lib/sequel/extensions/pagination.rb +35 -28
- data/lib/sequel/extensions/pg_array.rb +227 -316
- data/lib/sequel/extensions/pg_array_ops.rb +19 -7
- data/lib/sequel/extensions/pg_enum.rb +69 -24
- data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
- data/lib/sequel/extensions/pg_hstore.rb +50 -59
- data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
- data/lib/sequel/extensions/pg_inet.rb +34 -15
- data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
- data/lib/sequel/extensions/pg_interval.rb +26 -26
- data/lib/sequel/extensions/pg_json.rb +422 -141
- data/lib/sequel/extensions/pg_json_ops.rb +248 -9
- data/lib/sequel/extensions/pg_loose_count.rb +5 -1
- data/lib/sequel/extensions/pg_range.rb +162 -146
- data/lib/sequel/extensions/pg_range_ops.rb +10 -5
- data/lib/sequel/extensions/pg_row.rb +53 -87
- data/lib/sequel/extensions/pg_row_ops.rb +36 -13
- data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
- data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
- data/lib/sequel/extensions/pretty_table.rb +4 -0
- data/lib/sequel/extensions/query.rb +12 -7
- data/lib/sequel/extensions/round_timestamps.rb +6 -9
- data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
- data/lib/sequel/extensions/s.rb +59 -0
- data/lib/sequel/extensions/schema_caching.rb +14 -1
- data/lib/sequel/extensions/schema_dumper.rb +83 -55
- data/lib/sequel/extensions/select_remove.rb +8 -4
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
- data/lib/sequel/extensions/server_block.rb +50 -17
- data/lib/sequel/extensions/server_logging.rb +61 -0
- data/lib/sequel/extensions/split_array_nil.rb +8 -4
- data/lib/sequel/extensions/sql_comments.rb +96 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -1
- data/lib/sequel/extensions/string_agg.rb +181 -0
- data/lib/sequel/extensions/string_date_time.rb +2 -0
- data/lib/sequel/extensions/symbol_aref.rb +53 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
- data/lib/sequel/extensions/synchronize_sql.rb +45 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
- data/lib/sequel/extensions/to_dot.rb +15 -5
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +36 -126
- data/lib/sequel/model/associations.rb +850 -257
- data/lib/sequel/model/base.rb +652 -764
- data/lib/sequel/model/dataset_module.rb +13 -10
- data/lib/sequel/model/default_inflections.rb +3 -1
- data/lib/sequel/model/errors.rb +3 -3
- data/lib/sequel/model/exceptions.rb +12 -12
- data/lib/sequel/model/inflections.rb +8 -19
- data/lib/sequel/model/plugins.rb +111 -0
- data/lib/sequel/plugins/accessed_columns.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +32 -7
- data/lib/sequel/plugins/after_initialize.rb +3 -1
- data/lib/sequel/plugins/association_dependencies.rb +27 -18
- data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
- data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
- data/lib/sequel/plugins/association_pks.rb +181 -83
- data/lib/sequel/plugins/association_proxies.rb +33 -9
- data/lib/sequel/plugins/auto_validations.rb +58 -23
- data/lib/sequel/plugins/before_after_save.rb +8 -0
- data/lib/sequel/plugins/blacklist_security.rb +23 -12
- data/lib/sequel/plugins/boolean_readers.rb +9 -6
- data/lib/sequel/plugins/boolean_subsets.rb +64 -0
- data/lib/sequel/plugins/caching.rb +27 -16
- data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
- data/lib/sequel/plugins/column_conflicts.rb +18 -3
- data/lib/sequel/plugins/column_select.rb +9 -5
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +36 -24
- data/lib/sequel/plugins/constraint_validations.rb +37 -16
- data/lib/sequel/plugins/csv_serializer.rb +58 -35
- data/lib/sequel/plugins/dataset_associations.rb +60 -18
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/defaults_setter.rb +74 -13
- data/lib/sequel/plugins/delay_add_association.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +65 -24
- data/lib/sequel/plugins/eager_each.rb +27 -3
- data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
- data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
- data/lib/sequel/plugins/error_splitter.rb +19 -12
- data/lib/sequel/plugins/finder.rb +246 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
- data/lib/sequel/plugins/force_encoding.rb +9 -12
- data/lib/sequel/plugins/hook_class_methods.rb +39 -54
- data/lib/sequel/plugins/input_transformer.rb +20 -10
- data/lib/sequel/plugins/insert_conflict.rb +72 -0
- data/lib/sequel/plugins/insert_returning_select.rb +4 -2
- data/lib/sequel/plugins/instance_filters.rb +12 -8
- data/lib/sequel/plugins/instance_hooks.rb +36 -17
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/inverted_subsets.rb +24 -13
- data/lib/sequel/plugins/json_serializer.rb +123 -47
- data/lib/sequel/plugins/lazy_attributes.rb +20 -14
- data/lib/sequel/plugins/list.rb +40 -26
- data/lib/sequel/plugins/many_through_many.rb +28 -12
- data/lib/sequel/plugins/modification_detection.rb +17 -5
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
- data/lib/sequel/plugins/nested_attributes.rb +55 -28
- data/lib/sequel/plugins/optimistic_locking.rb +5 -3
- data/lib/sequel/plugins/pg_array_associations.rb +52 -18
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
- data/lib/sequel/plugins/pg_row.rb +7 -51
- data/lib/sequel/plugins/prepared_statements.rb +53 -72
- data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
- data/lib/sequel/plugins/rcte_tree.rb +43 -63
- data/lib/sequel/plugins/serialization.rb +37 -44
- data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
- data/lib/sequel/plugins/sharding.rb +17 -10
- data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
- data/lib/sequel/plugins/singular_table_names.rb +2 -0
- data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
- data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
- data/lib/sequel/plugins/split_values.rb +13 -6
- data/lib/sequel/plugins/static_cache.rb +79 -53
- data/lib/sequel/plugins/static_cache_cache.rb +53 -0
- data/lib/sequel/plugins/string_stripper.rb +5 -3
- data/lib/sequel/plugins/subclasses.rb +20 -2
- data/lib/sequel/plugins/subset_conditions.rb +48 -0
- data/lib/sequel/plugins/table_select.rb +4 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
- data/lib/sequel/plugins/throw_failures.rb +110 -0
- data/lib/sequel/plugins/timestamps.rb +22 -8
- data/lib/sequel/plugins/touch.rb +21 -8
- data/lib/sequel/plugins/tree.rb +57 -30
- data/lib/sequel/plugins/typecast_on_load.rb +14 -4
- data/lib/sequel/plugins/unlimited_update.rb +3 -7
- data/lib/sequel/plugins/update_or_create.rb +6 -4
- data/lib/sequel/plugins/update_primary_key.rb +3 -1
- data/lib/sequel/plugins/update_refresh.rb +28 -15
- data/lib/sequel/plugins/uuid.rb +70 -0
- data/lib/sequel/plugins/validate_associated.rb +20 -0
- data/lib/sequel/plugins/validation_class_methods.rb +40 -19
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +49 -31
- data/lib/sequel/plugins/whitelist_security.rb +122 -0
- data/lib/sequel/plugins/xml_serializer.rb +31 -30
- data/lib/sequel/sql.rb +479 -329
- data/lib/sequel/timezones.rb +62 -32
- data/lib/sequel/version.rb +10 -3
- metadata +177 -477
- data/Rakefile +0 -165
- data/doc/active_record.rdoc +0 -912
- data/doc/release_notes/1.0.txt +0 -38
- data/doc/release_notes/1.1.txt +0 -143
- data/doc/release_notes/1.3.txt +0 -101
- data/doc/release_notes/1.4.0.txt +0 -53
- data/doc/release_notes/1.5.0.txt +0 -155
- data/doc/release_notes/2.0.0.txt +0 -298
- data/doc/release_notes/2.1.0.txt +0 -271
- data/doc/release_notes/2.10.0.txt +0 -328
- data/doc/release_notes/2.11.0.txt +0 -215
- data/doc/release_notes/2.12.0.txt +0 -534
- data/doc/release_notes/2.2.0.txt +0 -253
- data/doc/release_notes/2.3.0.txt +0 -88
- data/doc/release_notes/2.4.0.txt +0 -106
- data/doc/release_notes/2.5.0.txt +0 -137
- data/doc/release_notes/2.6.0.txt +0 -157
- data/doc/release_notes/2.7.0.txt +0 -166
- data/doc/release_notes/2.8.0.txt +0 -171
- data/doc/release_notes/2.9.0.txt +0 -97
- data/doc/release_notes/3.0.0.txt +0 -221
- data/doc/release_notes/3.1.0.txt +0 -406
- data/doc/release_notes/3.10.0.txt +0 -286
- data/doc/release_notes/3.11.0.txt +0 -254
- data/doc/release_notes/3.12.0.txt +0 -304
- data/doc/release_notes/3.13.0.txt +0 -210
- data/doc/release_notes/3.14.0.txt +0 -118
- data/doc/release_notes/3.15.0.txt +0 -78
- data/doc/release_notes/3.16.0.txt +0 -45
- data/doc/release_notes/3.17.0.txt +0 -58
- data/doc/release_notes/3.18.0.txt +0 -120
- data/doc/release_notes/3.19.0.txt +0 -67
- data/doc/release_notes/3.2.0.txt +0 -268
- data/doc/release_notes/3.20.0.txt +0 -41
- data/doc/release_notes/3.21.0.txt +0 -87
- data/doc/release_notes/3.22.0.txt +0 -39
- data/doc/release_notes/3.23.0.txt +0 -172
- data/doc/release_notes/3.24.0.txt +0 -420
- data/doc/release_notes/3.25.0.txt +0 -88
- data/doc/release_notes/3.26.0.txt +0 -88
- data/doc/release_notes/3.27.0.txt +0 -82
- data/doc/release_notes/3.28.0.txt +0 -304
- data/doc/release_notes/3.29.0.txt +0 -459
- data/doc/release_notes/3.3.0.txt +0 -192
- data/doc/release_notes/3.30.0.txt +0 -135
- data/doc/release_notes/3.31.0.txt +0 -146
- data/doc/release_notes/3.32.0.txt +0 -202
- data/doc/release_notes/3.33.0.txt +0 -157
- data/doc/release_notes/3.34.0.txt +0 -671
- data/doc/release_notes/3.35.0.txt +0 -144
- data/doc/release_notes/3.36.0.txt +0 -245
- data/doc/release_notes/3.37.0.txt +0 -338
- data/doc/release_notes/3.38.0.txt +0 -234
- data/doc/release_notes/3.39.0.txt +0 -237
- data/doc/release_notes/3.4.0.txt +0 -325
- data/doc/release_notes/3.40.0.txt +0 -73
- data/doc/release_notes/3.41.0.txt +0 -155
- data/doc/release_notes/3.42.0.txt +0 -74
- data/doc/release_notes/3.43.0.txt +0 -105
- data/doc/release_notes/3.44.0.txt +0 -152
- data/doc/release_notes/3.45.0.txt +0 -179
- data/doc/release_notes/3.46.0.txt +0 -122
- data/doc/release_notes/3.47.0.txt +0 -270
- data/doc/release_notes/3.48.0.txt +0 -477
- data/doc/release_notes/3.5.0.txt +0 -510
- data/doc/release_notes/3.6.0.txt +0 -366
- data/doc/release_notes/3.7.0.txt +0 -179
- data/doc/release_notes/3.8.0.txt +0 -151
- data/doc/release_notes/3.9.0.txt +0 -233
- data/doc/release_notes/4.0.0.txt +0 -262
- data/doc/release_notes/4.1.0.txt +0 -85
- data/doc/release_notes/4.10.0.txt +0 -226
- data/doc/release_notes/4.11.0.txt +0 -147
- data/doc/release_notes/4.12.0.txt +0 -105
- data/doc/release_notes/4.13.0.txt +0 -169
- data/doc/release_notes/4.14.0.txt +0 -68
- data/doc/release_notes/4.15.0.txt +0 -56
- data/doc/release_notes/4.16.0.txt +0 -36
- data/doc/release_notes/4.17.0.txt +0 -38
- data/doc/release_notes/4.18.0.txt +0 -36
- data/doc/release_notes/4.19.0.txt +0 -45
- data/doc/release_notes/4.2.0.txt +0 -129
- data/doc/release_notes/4.20.0.txt +0 -79
- data/doc/release_notes/4.21.0.txt +0 -94
- data/doc/release_notes/4.22.0.txt +0 -72
- data/doc/release_notes/4.23.0.txt +0 -65
- data/doc/release_notes/4.24.0.txt +0 -99
- data/doc/release_notes/4.25.0.txt +0 -181
- data/doc/release_notes/4.26.0.txt +0 -44
- data/doc/release_notes/4.3.0.txt +0 -40
- data/doc/release_notes/4.4.0.txt +0 -92
- data/doc/release_notes/4.5.0.txt +0 -34
- data/doc/release_notes/4.6.0.txt +0 -30
- data/doc/release_notes/4.7.0.txt +0 -103
- data/doc/release_notes/4.8.0.txt +0 -175
- data/doc/release_notes/4.9.0.txt +0 -190
- data/lib/sequel/adapters/cubrid.rb +0 -142
- data/lib/sequel/adapters/do.rb +0 -156
- data/lib/sequel/adapters/do/mysql.rb +0 -64
- data/lib/sequel/adapters/do/postgres.rb +0 -42
- data/lib/sequel/adapters/do/sqlite3.rb +0 -40
- data/lib/sequel/adapters/jdbc/as400.rb +0 -82
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
- data/lib/sequel/adapters/odbc/progress.rb +0 -8
- data/lib/sequel/adapters/shared/cubrid.rb +0 -243
- data/lib/sequel/adapters/shared/firebird.rb +0 -245
- data/lib/sequel/adapters/shared/informix.rb +0 -52
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
- data/lib/sequel/adapters/shared/progress.rb +0 -38
- data/lib/sequel/adapters/swift.rb +0 -158
- data/lib/sequel/adapters/swift/mysql.rb +0 -47
- data/lib/sequel/adapters/swift/postgres.rb +0 -45
- data/lib/sequel/adapters/swift/sqlite.rb +0 -47
- data/lib/sequel/adapters/utils/pg_types.rb +0 -68
- data/lib/sequel/dataset/mutation.rb +0 -109
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
- data/lib/sequel/extensions/filter_having.rb +0 -59
- data/lib/sequel/extensions/hash_aliases.rb +0 -45
- data/lib/sequel/extensions/meta_def.rb +0 -31
- data/lib/sequel/extensions/query_literals.rb +0 -80
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
- data/lib/sequel/extensions/set_overrides.rb +0 -72
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/association_autoreloading.rb +0 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
- data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
- data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
- data/lib/sequel/plugins/schema.rb +0 -80
- data/lib/sequel/plugins/scissors.rb +0 -33
- data/spec/adapters/db2_spec.rb +0 -160
- data/spec/adapters/firebird_spec.rb +0 -411
- data/spec/adapters/informix_spec.rb +0 -100
- data/spec/adapters/mssql_spec.rb +0 -706
- data/spec/adapters/mysql_spec.rb +0 -1287
- data/spec/adapters/oracle_spec.rb +0 -313
- data/spec/adapters/postgres_spec.rb +0 -3725
- data/spec/adapters/spec_helper.rb +0 -43
- data/spec/adapters/sqlanywhere_spec.rb +0 -170
- data/spec/adapters/sqlite_spec.rb +0 -653
- data/spec/bin_spec.rb +0 -254
- data/spec/core/connection_pool_spec.rb +0 -1016
- data/spec/core/database_spec.rb +0 -2531
- data/spec/core/dataset_spec.rb +0 -5098
- data/spec/core/deprecated_spec.rb +0 -70
- data/spec/core/expression_filters_spec.rb +0 -1243
- data/spec/core/mock_adapter_spec.rb +0 -462
- data/spec/core/object_graph_spec.rb +0 -303
- data/spec/core/placeholder_literalizer_spec.rb +0 -163
- data/spec/core/schema_generator_spec.rb +0 -179
- data/spec/core/schema_spec.rb +0 -1659
- data/spec/core/spec_helper.rb +0 -34
- data/spec/core/version_spec.rb +0 -7
- data/spec/core_extensions_spec.rb +0 -699
- data/spec/extensions/accessed_columns_spec.rb +0 -51
- data/spec/extensions/active_model_spec.rb +0 -123
- data/spec/extensions/after_initialize_spec.rb +0 -24
- data/spec/extensions/arbitrary_servers_spec.rb +0 -109
- data/spec/extensions/association_dependencies_spec.rb +0 -117
- data/spec/extensions/association_pks_spec.rb +0 -365
- data/spec/extensions/association_proxies_spec.rb +0 -86
- data/spec/extensions/auto_validations_spec.rb +0 -192
- data/spec/extensions/blacklist_security_spec.rb +0 -88
- data/spec/extensions/blank_spec.rb +0 -69
- data/spec/extensions/boolean_readers_spec.rb +0 -93
- data/spec/extensions/caching_spec.rb +0 -270
- data/spec/extensions/class_table_inheritance_spec.rb +0 -420
- data/spec/extensions/column_conflicts_spec.rb +0 -60
- data/spec/extensions/column_select_spec.rb +0 -108
- data/spec/extensions/columns_introspection_spec.rb +0 -91
- data/spec/extensions/composition_spec.rb +0 -242
- data/spec/extensions/connection_validator_spec.rb +0 -120
- data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
- data/spec/extensions/constraint_validations_spec.rb +0 -325
- data/spec/extensions/core_refinements_spec.rb +0 -519
- data/spec/extensions/csv_serializer_spec.rb +0 -173
- data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
- data/spec/extensions/dataset_associations_spec.rb +0 -311
- data/spec/extensions/dataset_source_alias_spec.rb +0 -51
- data/spec/extensions/date_arithmetic_spec.rb +0 -150
- data/spec/extensions/defaults_setter_spec.rb +0 -101
- data/spec/extensions/delay_add_association_spec.rb +0 -52
- data/spec/extensions/dirty_spec.rb +0 -180
- data/spec/extensions/eager_each_spec.rb +0 -42
- data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
- data/spec/extensions/error_splitter_spec.rb +0 -18
- data/spec/extensions/error_sql_spec.rb +0 -20
- data/spec/extensions/eval_inspect_spec.rb +0 -73
- data/spec/extensions/filter_having_spec.rb +0 -40
- data/spec/extensions/force_encoding_spec.rb +0 -114
- data/spec/extensions/from_block_spec.rb +0 -21
- data/spec/extensions/graph_each_spec.rb +0 -109
- data/spec/extensions/hash_aliases_spec.rb +0 -24
- data/spec/extensions/hook_class_methods_spec.rb +0 -429
- data/spec/extensions/inflector_spec.rb +0 -183
- data/spec/extensions/input_transformer_spec.rb +0 -54
- data/spec/extensions/insert_returning_select_spec.rb +0 -46
- data/spec/extensions/instance_filters_spec.rb +0 -79
- data/spec/extensions/instance_hooks_spec.rb +0 -276
- data/spec/extensions/inverted_subsets_spec.rb +0 -33
- data/spec/extensions/json_serializer_spec.rb +0 -291
- data/spec/extensions/lazy_attributes_spec.rb +0 -170
- data/spec/extensions/list_spec.rb +0 -267
- data/spec/extensions/looser_typecasting_spec.rb +0 -43
- data/spec/extensions/many_through_many_spec.rb +0 -2172
- data/spec/extensions/meta_def_spec.rb +0 -21
- data/spec/extensions/migration_spec.rb +0 -712
- data/spec/extensions/modification_detection_spec.rb +0 -80
- data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
- data/spec/extensions/named_timezones_spec.rb +0 -108
- data/spec/extensions/nested_attributes_spec.rb +0 -697
- data/spec/extensions/null_dataset_spec.rb +0 -85
- data/spec/extensions/optimistic_locking_spec.rb +0 -128
- data/spec/extensions/pagination_spec.rb +0 -118
- data/spec/extensions/pg_array_associations_spec.rb +0 -736
- data/spec/extensions/pg_array_ops_spec.rb +0 -143
- data/spec/extensions/pg_array_spec.rb +0 -395
- data/spec/extensions/pg_enum_spec.rb +0 -92
- data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
- data/spec/extensions/pg_hstore_spec.rb +0 -206
- data/spec/extensions/pg_inet_ops_spec.rb +0 -101
- data/spec/extensions/pg_inet_spec.rb +0 -52
- data/spec/extensions/pg_interval_spec.rb +0 -76
- data/spec/extensions/pg_json_ops_spec.rb +0 -229
- data/spec/extensions/pg_json_spec.rb +0 -218
- data/spec/extensions/pg_loose_count_spec.rb +0 -17
- data/spec/extensions/pg_range_ops_spec.rb +0 -58
- data/spec/extensions/pg_range_spec.rb +0 -404
- data/spec/extensions/pg_row_ops_spec.rb +0 -60
- data/spec/extensions/pg_row_plugin_spec.rb +0 -62
- data/spec/extensions/pg_row_spec.rb +0 -360
- data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
- data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
- data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
- data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
- data/spec/extensions/prepared_statements_spec.rb +0 -103
- data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
- data/spec/extensions/pretty_table_spec.rb +0 -92
- data/spec/extensions/query_literals_spec.rb +0 -183
- data/spec/extensions/query_spec.rb +0 -102
- data/spec/extensions/rcte_tree_spec.rb +0 -392
- data/spec/extensions/round_timestamps_spec.rb +0 -43
- data/spec/extensions/schema_caching_spec.rb +0 -41
- data/spec/extensions/schema_dumper_spec.rb +0 -789
- data/spec/extensions/schema_spec.rb +0 -117
- data/spec/extensions/scissors_spec.rb +0 -26
- data/spec/extensions/select_remove_spec.rb +0 -38
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
- data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
- data/spec/extensions/serialization_spec.rb +0 -362
- data/spec/extensions/server_block_spec.rb +0 -90
- data/spec/extensions/set_overrides_spec.rb +0 -61
- data/spec/extensions/sharding_spec.rb +0 -198
- data/spec/extensions/shared_caching_spec.rb +0 -175
- data/spec/extensions/single_table_inheritance_spec.rb +0 -297
- data/spec/extensions/singular_table_names_spec.rb +0 -22
- data/spec/extensions/skip_create_refresh_spec.rb +0 -17
- data/spec/extensions/spec_helper.rb +0 -71
- data/spec/extensions/split_array_nil_spec.rb +0 -24
- data/spec/extensions/split_values_spec.rb +0 -22
- data/spec/extensions/sql_expr_spec.rb +0 -60
- data/spec/extensions/static_cache_spec.rb +0 -361
- data/spec/extensions/string_date_time_spec.rb +0 -95
- data/spec/extensions/string_stripper_spec.rb +0 -68
- data/spec/extensions/subclasses_spec.rb +0 -66
- data/spec/extensions/table_select_spec.rb +0 -71
- data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
- data/spec/extensions/thread_local_timezones_spec.rb +0 -67
- data/spec/extensions/timestamps_spec.rb +0 -175
- data/spec/extensions/to_dot_spec.rb +0 -154
- data/spec/extensions/touch_spec.rb +0 -203
- data/spec/extensions/tree_spec.rb +0 -274
- data/spec/extensions/typecast_on_load_spec.rb +0 -80
- data/spec/extensions/unlimited_update_spec.rb +0 -20
- data/spec/extensions/update_or_create_spec.rb +0 -87
- data/spec/extensions/update_primary_key_spec.rb +0 -100
- data/spec/extensions/update_refresh_spec.rb +0 -53
- data/spec/extensions/validate_associated_spec.rb +0 -52
- data/spec/extensions/validation_class_methods_spec.rb +0 -1027
- data/spec/extensions/validation_helpers_spec.rb +0 -541
- data/spec/extensions/xml_serializer_spec.rb +0 -207
- data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
- data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
- data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
- data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
- data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
- data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
- data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
- data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
- data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/reversible_migrations/001_reversible.rb +0 -5
- data/spec/files/reversible_migrations/002_reversible.rb +0 -5
- data/spec/files/reversible_migrations/003_reversible.rb +0 -5
- data/spec/files/reversible_migrations/004_reversible.rb +0 -5
- data/spec/files/reversible_migrations/005_reversible.rb +0 -10
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
- data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
- data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
- data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
- data/spec/guards_helper.rb +0 -55
- data/spec/integration/associations_test.rb +0 -2454
- data/spec/integration/database_test.rb +0 -113
- data/spec/integration/dataset_test.rb +0 -1808
- data/spec/integration/eager_loader_test.rb +0 -687
- data/spec/integration/migrator_test.rb +0 -240
- data/spec/integration/model_test.rb +0 -226
- data/spec/integration/plugin_test.rb +0 -2240
- data/spec/integration/prepared_statement_test.rb +0 -467
- data/spec/integration/schema_test.rb +0 -817
- data/spec/integration/spec_helper.rb +0 -48
- data/spec/integration/timezone_test.rb +0 -86
- data/spec/integration/transaction_test.rb +0 -374
- data/spec/integration/type_test.rb +0 -133
- data/spec/model/association_reflection_spec.rb +0 -525
- data/spec/model/associations_spec.rb +0 -4426
- data/spec/model/base_spec.rb +0 -759
- data/spec/model/class_dataset_methods_spec.rb +0 -146
- data/spec/model/dataset_methods_spec.rb +0 -149
- data/spec/model/eager_loading_spec.rb +0 -2137
- data/spec/model/hooks_spec.rb +0 -604
- data/spec/model/inflector_spec.rb +0 -26
- data/spec/model/model_spec.rb +0 -982
- data/spec/model/plugins_spec.rb +0 -299
- data/spec/model/record_spec.rb +0 -2147
- data/spec/model/spec_helper.rb +0 -46
- data/spec/model/validations_spec.rb +0 -193
- data/spec/sequel_coverage.rb +0 -15
- data/spec/spec_config.rb +0 -10
data/lib/sequel/dataset/sql.rb
CHANGED
|
@@ -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(:
|
|
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
|
|
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
|
|
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 =
|
|
50
|
-
|
|
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 =
|
|
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
|
|
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(:
|
|
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 <<
|
|
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
|
-
|
|
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
|
-
|
|
279
|
-
|
|
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 <<
|
|
278
|
+
sql << '(NULL)'
|
|
360
279
|
else
|
|
361
|
-
sql <<
|
|
280
|
+
sql << '('
|
|
362
281
|
expression_list_append(sql, a)
|
|
363
|
-
sql <<
|
|
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 ?
|
|
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 <<
|
|
297
|
+
sql << '(CASE'
|
|
379
298
|
if ce.expression?
|
|
380
|
-
sql <<
|
|
299
|
+
sql << ' '
|
|
381
300
|
literal_append(sql, ce.expression)
|
|
382
301
|
end
|
|
383
|
-
w =
|
|
384
|
-
t =
|
|
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 <<
|
|
310
|
+
sql << " ELSE "
|
|
392
311
|
literal_append(sql, ce.default)
|
|
393
|
-
sql <<
|
|
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 <<
|
|
317
|
+
sql << 'CAST('
|
|
399
318
|
literal_append(sql, expr)
|
|
400
|
-
sql << AS << db.cast_type_literal(type).to_s
|
|
401
|
-
sql <<
|
|
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
|
|
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 <<
|
|
417
|
-
literal_append(sql, args
|
|
418
|
-
sql <<
|
|
419
|
-
sql << val <<
|
|
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
|
|
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
|
|
427
|
-
vals = args
|
|
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 <<
|
|
370
|
+
sql << '('
|
|
452
371
|
literal_append(sql, cols)
|
|
453
|
-
sql <<
|
|
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 <<
|
|
378
|
+
sql << ')'
|
|
460
379
|
end
|
|
461
380
|
else
|
|
462
|
-
sql <<
|
|
381
|
+
sql << '('
|
|
463
382
|
literal_append(sql, cols)
|
|
464
|
-
sql <<
|
|
383
|
+
sql << ' ' << op.to_s << ' '
|
|
465
384
|
literal_append(sql, vals)
|
|
466
|
-
sql <<
|
|
385
|
+
sql << ')'
|
|
467
386
|
end
|
|
468
387
|
when :LIKE, :'NOT LIKE'
|
|
469
|
-
sql <<
|
|
470
|
-
literal_append(sql, args
|
|
471
|
-
sql <<
|
|
472
|
-
literal_append(sql, args
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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 <<
|
|
483
|
-
literal_append(sql, args
|
|
484
|
-
sql <<
|
|
485
|
-
literal_append(sql, args
|
|
486
|
-
sql <<
|
|
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 <<
|
|
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 <<
|
|
419
|
+
sql << ')'
|
|
497
420
|
when :NOT
|
|
498
|
-
sql <<
|
|
499
|
-
literal_append(sql, args
|
|
421
|
+
sql << 'NOT '
|
|
422
|
+
literal_append(sql, args[0])
|
|
500
423
|
when :NOOP
|
|
501
|
-
literal_append(sql, args
|
|
424
|
+
literal_append(sql, args[0])
|
|
502
425
|
when :'B~'
|
|
503
|
-
sql <<
|
|
504
|
-
literal_append(sql, args
|
|
426
|
+
sql << '~'
|
|
427
|
+
literal_append(sql, args[0])
|
|
505
428
|
when :extract
|
|
506
|
-
sql <<
|
|
507
|
-
literal_append(sql, args
|
|
508
|
-
sql <<
|
|
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]
|
|
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(
|
|
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 <<
|
|
494
|
+
sql << '('
|
|
495
|
+
if filter = opts[:filter]
|
|
496
|
+
filter = filter_expr(filter, &opts[:filter_block])
|
|
497
|
+
end
|
|
567
498
|
if opts[:*]
|
|
568
|
-
|
|
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 <<
|
|
571
|
-
|
|
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 <<
|
|
518
|
+
sql << ')'
|
|
574
519
|
|
|
575
520
|
if group = opts[:within_group]
|
|
576
|
-
sql <<
|
|
521
|
+
sql << " WITHIN GROUP (ORDER BY "
|
|
577
522
|
expression_list_append(sql, group)
|
|
578
|
-
sql <<
|
|
523
|
+
sql << ')'
|
|
579
524
|
end
|
|
580
525
|
|
|
581
|
-
if filter
|
|
582
|
-
sql << FILTER
|
|
583
|
-
literal_append(sql,
|
|
584
|
-
sql <<
|
|
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 <<
|
|
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 <<
|
|
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 <<
|
|
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 <<
|
|
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
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
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 <<
|
|
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
|
-
|
|
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
|
-
|
|
670
|
-
previous, q, str = str.partition(
|
|
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
|
|
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 <<
|
|
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 <<
|
|
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 <<
|
|
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 <<
|
|
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(:
|
|
757
|
-
# ds.split_qualifiers(Sequel
|
|
758
|
-
# ds.split_qualifiers(Sequel.qualify(:
|
|
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
|
-
|
|
772
|
-
|
|
773
|
-
|
|
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 <<
|
|
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 <<
|
|
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 =
|
|
792
|
-
|
|
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
|
-
|
|
771
|
+
|
|
772
|
+
if part = opts[:partition]
|
|
797
773
|
sql << space_s if space
|
|
798
|
-
sql <<
|
|
774
|
+
sql << "PARTITION BY "
|
|
799
775
|
expression_list_append(sql, Array(part))
|
|
800
776
|
space = true
|
|
801
777
|
end
|
|
802
|
-
|
|
778
|
+
|
|
779
|
+
if order = opts[:order]
|
|
803
780
|
sql << space_s if space
|
|
804
|
-
sql <<
|
|
781
|
+
sql << "ORDER BY "
|
|
805
782
|
expression_list_append(sql, Array(order))
|
|
806
783
|
space = true
|
|
807
784
|
end
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 <<
|
|
910
|
+
sql << '('
|
|
892
911
|
identifier_list_append(sql, column_aliases)
|
|
893
|
-
sql <<
|
|
912
|
+
sql << ')'
|
|
894
913
|
end
|
|
895
914
|
end
|
|
896
915
|
|
|
897
|
-
#
|
|
898
|
-
|
|
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
|
-
#
|
|
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 <<
|
|
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
|
|
955
|
+
args[0]
|
|
928
956
|
when 2
|
|
929
|
-
yield args
|
|
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 <<
|
|
958
|
-
literal_append(sql, args
|
|
959
|
-
sql <<
|
|
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
|
-
:"#{
|
|
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? ?
|
|
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 =
|
|
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 =
|
|
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 <<
|
|
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(
|
|
1039
|
-
if m ==
|
|
1040
|
-
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
-
#
|
|
1096
|
-
# identifier_output_method.
|
|
1132
|
+
# Upcase identifiers by default when inputting them into the database.
|
|
1097
1133
|
def input_identifier(v)
|
|
1098
|
-
|
|
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 <<
|
|
1149
|
+
sql << ' ('
|
|
1114
1150
|
identifier_list_append(sql, columns)
|
|
1115
|
-
sql <<
|
|
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 <<
|
|
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 <<
|
|
1175
|
+
sql << ' '
|
|
1134
1176
|
subselect_sql_append(sql, values)
|
|
1135
1177
|
when LiteralString
|
|
1136
|
-
sql <<
|
|
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(
|
|
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 <<
|
|
1222
|
+
sql << 'LATERAL ' if v.opts[:lateral]
|
|
1223
|
+
sql << '('
|
|
1182
1224
|
subselect_sql_append(sql, v)
|
|
1183
|
-
sql <<
|
|
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(
|
|
1231
|
+
v.strftime("DATE '%Y-%m-%d'")
|
|
1190
1232
|
else
|
|
1191
|
-
v.strftime(
|
|
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
|
-
|
|
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 <<
|
|
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 <<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1371
|
+
# Qualify the given expression to the given table.
|
|
1325
1372
|
def qualified_expression(e, table)
|
|
1326
|
-
Qualifier.new(
|
|
1373
|
+
Qualifier.new(table).transform(e)
|
|
1327
1374
|
end
|
|
1328
1375
|
|
|
1329
1376
|
def select_columns_sql(sql)
|
|
1330
|
-
sql <<
|
|
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 <<
|
|
1385
|
+
sql << " ON ("
|
|
1339
1386
|
expression_list_append(sql, distinct)
|
|
1340
|
-
sql <<
|
|
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.
|
|
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 <<
|
|
1352
|
-
sql << ALL if all
|
|
1353
|
-
sql <<
|
|
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 <<
|
|
1416
|
+
sql << " GROUP BY "
|
|
1370
1417
|
if go = @opts[:group_options]
|
|
1371
1418
|
if go == :"grouping sets"
|
|
1372
|
-
sql << go.to_s.upcase <<
|
|
1419
|
+
sql << go.to_s.upcase << '('
|
|
1373
1420
|
grouping_element_list_append(sql, group)
|
|
1374
|
-
sql <<
|
|
1421
|
+
sql << ')'
|
|
1375
1422
|
elsif uses_with_rollup?
|
|
1376
1423
|
expression_list_append(sql, group)
|
|
1377
|
-
sql <<
|
|
1424
|
+
sql << " WITH " << go.to_s.upcase
|
|
1378
1425
|
else
|
|
1379
|
-
sql << go.to_s.upcase <<
|
|
1426
|
+
sql << go.to_s.upcase << '('
|
|
1380
1427
|
expression_list_append(sql, group)
|
|
1381
|
-
sql <<
|
|
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 <<
|
|
1465
|
+
sql << ' FOR UPDATE'
|
|
1419
1466
|
when String
|
|
1420
|
-
sql <<
|
|
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 <<
|
|
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 =
|
|
1523
|
+
comma = ', '
|
|
1461
1524
|
ws.each do |w|
|
|
1462
1525
|
sql << comma if c
|
|
1463
|
-
|
|
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 <<
|
|
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
|
-
|
|
1537
|
+
"WITH "
|
|
1482
1538
|
end
|
|
1483
1539
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
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
|
-
#
|
|
1490
|
-
def skip_symbol_cache
|
|
1491
|
-
@skip_symbol_cache
|
|
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
|
|
1599
|
+
# Append literalization of the subselect to SQL string.
|
|
1533
1600
|
def subselect_sql_append(sql, ds)
|
|
1534
|
-
|
|
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 <<
|
|
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 =
|
|
1637
|
+
eq = ' = '
|
|
1561
1638
|
values.each do |k, v|
|
|
1562
|
-
sql <<
|
|
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
|