sequel 4.46.0 → 4.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +210 -0
- data/Rakefile +1 -1
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.47.0.txt +56 -0
- data/doc/release_notes/4.48.0.txt +293 -0
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ado/access.rb +2 -1
- data/lib/sequel/adapters/do/postgres.rb +5 -2
- data/lib/sequel/adapters/ibmdb.rb +30 -8
- data/lib/sequel/adapters/jdbc/as400.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +12 -3
- data/lib/sequel/adapters/jdbc/derby.rb +4 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
- data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
- data/lib/sequel/adapters/jdbc.rb +39 -23
- data/lib/sequel/adapters/mock.rb +27 -19
- data/lib/sequel/adapters/mysql.rb +17 -16
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/oracle.rb +5 -9
- data/lib/sequel/adapters/postgres.rb +91 -103
- data/lib/sequel/adapters/shared/db2.rb +22 -6
- data/lib/sequel/adapters/shared/mssql.rb +5 -4
- data/lib/sequel/adapters/shared/mysql.rb +79 -25
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/adapters/shared/postgres.rb +199 -95
- data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
- data/lib/sequel/adapters/shared/sqlite.rb +72 -82
- data/lib/sequel/adapters/sqlanywhere.rb +4 -1
- data/lib/sequel/adapters/sqlite.rb +5 -3
- data/lib/sequel/adapters/swift/postgres.rb +5 -2
- data/lib/sequel/adapters/tinytds.rb +0 -5
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
- data/lib/sequel/adapters/utils/pg_types.rb +2 -76
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/core.rb +2 -2
- data/lib/sequel/database/connecting.rb +8 -8
- data/lib/sequel/database/dataset.rb +6 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/database/misc.rb +1 -1
- data/lib/sequel/database/query.rb +3 -0
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset/actions.rb +72 -10
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/graph.rb +1 -1
- data/lib/sequel/dataset/misc.rb +1 -0
- data/lib/sequel/dataset/prepared_statements.rb +3 -3
- data/lib/sequel/dataset/query.rb +22 -11
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/core_extensions.rb +4 -1
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
- data/lib/sequel/extensions/filter_having.rb +2 -0
- data/lib/sequel/extensions/freeze_datasets.rb +2 -0
- data/lib/sequel/extensions/from_block.rb +1 -1
- data/lib/sequel/extensions/graph_each.rb +2 -2
- data/lib/sequel/extensions/hash_aliases.rb +2 -0
- data/lib/sequel/extensions/identifier_mangling.rb +0 -7
- data/lib/sequel/extensions/meta_def.rb +2 -0
- data/lib/sequel/extensions/migration.rb +11 -8
- data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +207 -130
- data/lib/sequel/extensions/pg_hstore.rb +38 -20
- data/lib/sequel/extensions/pg_inet.rb +18 -6
- data/lib/sequel/extensions/pg_interval.rb +19 -12
- data/lib/sequel/extensions/pg_json.rb +25 -14
- data/lib/sequel/extensions/pg_json_ops.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +133 -100
- data/lib/sequel/extensions/pg_range_ops.rb +4 -3
- data/lib/sequel/extensions/pg_row.rb +68 -39
- data/lib/sequel/extensions/pg_row_ops.rb +11 -5
- data/lib/sequel/extensions/query_literals.rb +2 -0
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
- data/lib/sequel/extensions/s.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +29 -25
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
- data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
- data/lib/sequel/extensions/server_block.rb +32 -15
- data/lib/sequel/extensions/set_overrides.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +0 -1
- data/lib/sequel/extensions/symbol_aref.rb +0 -4
- data/lib/sequel/model/associations.rb +35 -7
- data/lib/sequel/model/base.rb +113 -87
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/model.rb +26 -58
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/association_autoreloading.rb +2 -0
- data/lib/sequel/plugins/association_dependencies.rb +3 -3
- data/lib/sequel/plugins/association_pks.rb +73 -46
- data/lib/sequel/plugins/association_proxies.rb +1 -1
- data/lib/sequel/plugins/auto_validations.rb +6 -2
- data/lib/sequel/plugins/boolean_readers.rb +2 -2
- data/lib/sequel/plugins/boolean_subsets.rb +1 -1
- data/lib/sequel/plugins/caching.rb +19 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
- data/lib/sequel/plugins/column_conflicts.rb +7 -2
- data/lib/sequel/plugins/column_select.rb +3 -3
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/csv_serializer.rb +8 -8
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/defaults_setter.rb +13 -1
- data/lib/sequel/plugins/eager_each.rb +1 -1
- data/lib/sequel/plugins/force_encoding.rb +2 -2
- data/lib/sequel/plugins/hook_class_methods.rb +9 -12
- data/lib/sequel/plugins/identifier_columns.rb +2 -0
- data/lib/sequel/plugins/instance_filters.rb +3 -1
- data/lib/sequel/plugins/instance_hooks.rb +17 -9
- data/lib/sequel/plugins/json_serializer.rb +19 -12
- data/lib/sequel/plugins/lazy_attributes.rb +8 -7
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
- data/lib/sequel/plugins/modification_detection.rb +3 -0
- data/lib/sequel/plugins/nested_attributes.rb +6 -2
- data/lib/sequel/plugins/pg_array_associations.rb +5 -0
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/plugins/rcte_tree.rb +4 -24
- data/lib/sequel/plugins/serialization.rb +9 -15
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
- data/lib/sequel/plugins/split_values.rb +6 -5
- data/lib/sequel/plugins/static_cache.rb +31 -25
- data/lib/sequel/plugins/subset_conditions.rb +3 -1
- data/lib/sequel/plugins/table_select.rb +1 -1
- data/lib/sequel/plugins/touch.rb +4 -2
- data/lib/sequel/plugins/validation_class_methods.rb +5 -6
- data/lib/sequel/plugins/validation_helpers.rb +14 -8
- data/lib/sequel/plugins/xml_serializer.rb +4 -4
- data/lib/sequel/sql.rb +18 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +115 -14
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +83 -29
- data/spec/adapters/oracle_spec.rb +28 -24
- data/spec/adapters/postgres_spec.rb +40 -24
- data/spec/adapters/sqlanywhere_spec.rb +88 -86
- data/spec/adapters/sqlite_spec.rb +29 -24
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +45 -14
- data/spec/core/database_spec.rb +155 -0
- data/spec/core/dataset_spec.rb +219 -36
- data/spec/core/schema_spec.rb +16 -0
- data/spec/core/spec_helper.rb +1 -0
- data/spec/core_extensions_spec.rb +6 -2
- data/spec/extensions/active_model_spec.rb +1 -1
- data/spec/extensions/arbitrary_servers_spec.rb +1 -1
- data/spec/extensions/association_pks_spec.rb +34 -2
- data/spec/extensions/auto_literal_strings_spec.rb +5 -1
- data/spec/extensions/auto_validations_spec.rb +2 -0
- data/spec/extensions/boolean_readers_spec.rb +1 -1
- data/spec/extensions/boolean_subsets_spec.rb +1 -1
- data/spec/extensions/class_table_inheritance_spec.rb +106 -19
- data/spec/extensions/column_conflicts_spec.rb +11 -0
- data/spec/extensions/column_select_spec.rb +1 -0
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/connection_validator_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +20 -8
- data/spec/extensions/defaults_setter_spec.rb +15 -1
- data/spec/extensions/filter_having_spec.rb +5 -3
- data/spec/extensions/hash_aliases_spec.rb +3 -1
- data/spec/extensions/identifier_columns_spec.rb +3 -1
- data/spec/extensions/implicit_subquery_spec.rb +4 -2
- data/spec/extensions/json_serializer_spec.rb +18 -0
- data/spec/extensions/lazy_attributes_spec.rb +3 -3
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/meta_def_spec.rb +9 -0
- data/spec/extensions/migration_spec.rb +3 -3
- data/spec/extensions/nested_attributes_spec.rb +14 -3
- data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_associations_spec.rb +29 -18
- data/spec/extensions/pg_array_spec.rb +44 -25
- data/spec/extensions/pg_hstore_spec.rb +10 -0
- data/spec/extensions/pg_inet_spec.rb +26 -0
- data/spec/extensions/pg_interval_spec.rb +20 -0
- data/spec/extensions/pg_json_spec.rb +24 -0
- data/spec/extensions/pg_range_spec.rb +98 -14
- data/spec/extensions/pg_row_spec.rb +14 -4
- data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
- data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +3 -1
- data/spec/extensions/schema_dumper_spec.rb +108 -94
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
- data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/server_block_spec.rb +7 -0
- data/spec/extensions/single_table_inheritance_spec.rb +17 -1
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/static_cache_spec.rb +75 -24
- data/spec/extensions/string_agg_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +9 -0
- data/spec/extensions/validation_helpers_spec.rb +10 -5
- data/spec/extensions/whitelist_security_spec.rb +26 -0
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/dataset_test.rb +45 -44
- data/spec/integration/model_test.rb +53 -4
- data/spec/integration/plugin_test.rb +28 -4
- data/spec/integration/prepared_statement_test.rb +3 -0
- data/spec/integration/schema_test.rb +21 -1
- data/spec/integration/transaction_test.rb +40 -40
- data/spec/model/association_reflection_spec.rb +43 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +20 -4
- data/spec/model/dataset_methods_spec.rb +12 -3
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +45 -1
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +11 -4
- data/spec/adapters/firebird_spec.rb +0 -405
- data/spec/adapters/informix_spec.rb +0 -100
|
@@ -5,89 +5,20 @@ Sequel.require 'adapters/shared/postgres'
|
|
|
5
5
|
begin
|
|
6
6
|
require 'pg'
|
|
7
7
|
|
|
8
|
+
Sequel::Postgres::PGError = PG::Error if defined?(PG::Error)
|
|
9
|
+
Sequel::Postgres::PGconn = PG::Connection if defined?(PG::Connection)
|
|
10
|
+
Sequel::Postgres::PGresult = PG::Result if defined?(PG::Result)
|
|
11
|
+
|
|
8
12
|
# Work around postgres-pr 0.7.0+ which ships with a pg.rb file
|
|
9
|
-
|
|
13
|
+
unless defined?(PG::Connection)
|
|
14
|
+
raise LoadError unless defined?(PGconn::CONNECTION_OK)
|
|
15
|
+
end
|
|
10
16
|
|
|
11
17
|
Sequel::Postgres::USES_PG = true
|
|
12
18
|
rescue LoadError => e
|
|
13
|
-
Sequel::Postgres::USES_PG = false
|
|
14
19
|
begin
|
|
15
|
-
require 'postgres'
|
|
16
|
-
|
|
17
|
-
# if pg, postgres, or postgres-pr is used.
|
|
18
|
-
class PGconn
|
|
19
|
-
unless method_defined?(:escape_string)
|
|
20
|
-
if self.respond_to?(:escape)
|
|
21
|
-
# If there is no escape_string instance method, but there is an
|
|
22
|
-
# escape class method, use that instead.
|
|
23
|
-
def escape_string(str)
|
|
24
|
-
Sequel::Postgres.force_standard_strings ? str.gsub("'", "''") : self.class.escape(str)
|
|
25
|
-
end
|
|
26
|
-
else
|
|
27
|
-
# Raise an error if no valid string escaping method can be found.
|
|
28
|
-
def escape_string(obj)
|
|
29
|
-
if Sequel::Postgres.force_standard_strings
|
|
30
|
-
str.gsub("'", "''")
|
|
31
|
-
else
|
|
32
|
-
raise Sequel::Error, "string escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
unless method_defined?(:escape_bytea)
|
|
38
|
-
if self.respond_to?(:escape_bytea)
|
|
39
|
-
# If there is no escape_bytea instance method, but there is an
|
|
40
|
-
# escape_bytea class method, use that instead.
|
|
41
|
-
def escape_bytea(obj)
|
|
42
|
-
self.class.escape_bytea(obj)
|
|
43
|
-
end
|
|
44
|
-
else
|
|
45
|
-
begin
|
|
46
|
-
require 'postgres-pr/typeconv/conv'
|
|
47
|
-
require 'postgres-pr/typeconv/bytea'
|
|
48
|
-
extend Postgres::Conversion
|
|
49
|
-
# If we are using postgres-pr, use the encode_bytea method from
|
|
50
|
-
# that.
|
|
51
|
-
def escape_bytea(obj)
|
|
52
|
-
self.class.encode_bytea(obj)
|
|
53
|
-
end
|
|
54
|
-
instance_eval{alias unescape_bytea decode_bytea}
|
|
55
|
-
rescue
|
|
56
|
-
# If no valid bytea escaping method can be found, create one that
|
|
57
|
-
# raises an error
|
|
58
|
-
def escape_bytea(obj)
|
|
59
|
-
raise Sequel::Error, "bytea escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
|
|
60
|
-
end
|
|
61
|
-
# If no valid bytea unescaping method can be found, create one that
|
|
62
|
-
# raises an error
|
|
63
|
-
def self.unescape_bytea(obj)
|
|
64
|
-
raise Sequel::Error, "bytea unescaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
alias_method :finish, :close unless method_defined?(:finish)
|
|
70
|
-
alias_method :async_exec, :exec unless method_defined?(:async_exec)
|
|
71
|
-
unless method_defined?(:block)
|
|
72
|
-
def block(timeout=nil)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
unless defined?(CONNECTION_OK)
|
|
76
|
-
CONNECTION_OK = -1
|
|
77
|
-
end
|
|
78
|
-
unless method_defined?(:status)
|
|
79
|
-
def status
|
|
80
|
-
CONNECTION_OK
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
class PGresult
|
|
85
|
-
alias_method :nfields, :num_fields unless method_defined?(:nfields)
|
|
86
|
-
alias_method :ntuples, :num_tuples unless method_defined?(:ntuples)
|
|
87
|
-
alias_method :ftype, :type unless method_defined?(:ftype)
|
|
88
|
-
alias_method :fname, :fieldname unless method_defined?(:fname)
|
|
89
|
-
alias_method :cmd_tuples, :cmdtuples unless method_defined?(:cmd_tuples)
|
|
90
|
-
end
|
|
20
|
+
require 'postgres-pr/postgres-compat'
|
|
21
|
+
Sequel::Postgres::USES_PG = false
|
|
91
22
|
rescue LoadError
|
|
92
23
|
raise e
|
|
93
24
|
end
|
|
@@ -95,14 +26,11 @@ end
|
|
|
95
26
|
|
|
96
27
|
module Sequel
|
|
97
28
|
module Postgres
|
|
98
|
-
|
|
99
|
-
|
|
29
|
+
# SEQUEL5: Remove
|
|
100
30
|
TYPE_CONVERTOR = Class.new do
|
|
101
31
|
def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
|
|
102
32
|
end.new
|
|
103
|
-
|
|
104
|
-
# SEQUEL5: Remove
|
|
105
|
-
PG_TYPES[17] = TYPE_CONVERTOR.method(:bytea)
|
|
33
|
+
Sequel::Deprecation.deprecate_constant(self, :TYPE_CONVERTOR)
|
|
106
34
|
|
|
107
35
|
if Sequel::Postgres::USES_PG
|
|
108
36
|
# Whether the given sequel_pg version integer is supported.
|
|
@@ -111,18 +39,22 @@ module Sequel
|
|
|
111
39
|
end
|
|
112
40
|
end
|
|
113
41
|
|
|
42
|
+
# SEQUEL5: Remove
|
|
114
43
|
@use_iso_date_format = true
|
|
115
|
-
|
|
116
44
|
class << self
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
45
|
+
def use_iso_date_format
|
|
46
|
+
Sequel::Deprecation.deprecate("Sequel::Postgres.use_iso_date_format", "Use the :use_iso_date_format Database option instead")
|
|
47
|
+
@use_iso_date_format
|
|
48
|
+
end
|
|
49
|
+
def use_iso_date_format=(v)
|
|
50
|
+
Sequel::Deprecation.deprecate("Sequel::Postgres.use_iso_date_format=", "Use the :use_iso_date_format Database option instead")
|
|
51
|
+
@use_iso_date_format = v
|
|
52
|
+
end
|
|
121
53
|
end
|
|
122
54
|
|
|
123
55
|
# PGconn subclass for connection specific methods used with the
|
|
124
|
-
# pg
|
|
125
|
-
class Adapter <
|
|
56
|
+
# pg or postgres-pr driver.
|
|
57
|
+
class Adapter < PGconn
|
|
126
58
|
# The underlying exception classes to reraise as disconnect errors
|
|
127
59
|
# instead of regular database errors.
|
|
128
60
|
DISCONNECT_ERROR_CLASSES = [IOError, Errno::EPIPE, Errno::ECONNRESET]
|
|
@@ -145,10 +77,49 @@ module Sequel
|
|
|
145
77
|
# errors.
|
|
146
78
|
DISCONNECT_ERROR_RE = /\A#{Regexp.union(disconnect_errors)}/
|
|
147
79
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
80
|
+
if USES_PG
|
|
81
|
+
# Hash of prepared statements for this connection. Keys are
|
|
82
|
+
# string names of the server side prepared statement, and values
|
|
83
|
+
# are SQL strings.
|
|
84
|
+
attr_reader :prepared_statements
|
|
85
|
+
else
|
|
86
|
+
# Make postgres-pr look like pg
|
|
87
|
+
CONNECTION_OK = -1
|
|
88
|
+
|
|
89
|
+
# Escape bytea values. Uses historical format instead of hex
|
|
90
|
+
# format for maximum compatibility.
|
|
91
|
+
def escape_bytea(str)
|
|
92
|
+
# each_byte used instead of [] for 1.9 compatibility
|
|
93
|
+
str.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{sprintf('%o', b.each_byte{|x| break x}).rjust(3, '0')}"}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Escape strings by doubling apostrophes. This only works if standard
|
|
97
|
+
# conforming strings are used.
|
|
98
|
+
def escape_string(str)
|
|
99
|
+
str.gsub("'", "''")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
alias finish close
|
|
103
|
+
|
|
104
|
+
def async_exec(sql)
|
|
105
|
+
PGresult.new(@conn.query(sql))
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def block(timeout=nil)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def status
|
|
112
|
+
CONNECTION_OK
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class PGresult < ::PGresult
|
|
116
|
+
alias nfields num_fields
|
|
117
|
+
alias ntuples num_tuples
|
|
118
|
+
alias ftype type
|
|
119
|
+
alias fname fieldname
|
|
120
|
+
alias cmd_tuples cmdtuples
|
|
121
|
+
end
|
|
122
|
+
end
|
|
152
123
|
|
|
153
124
|
# Raise a Sequel::DatabaseDisconnectError if a one of the disconnect
|
|
154
125
|
# error classes is raised, or a PGError is raised and the connection
|
|
@@ -247,7 +218,8 @@ module Sequel
|
|
|
247
218
|
:user => opts[:user],
|
|
248
219
|
:password => opts[:password],
|
|
249
220
|
:connect_timeout => opts[:connect_timeout] || 20,
|
|
250
|
-
:sslmode => opts[:sslmode]
|
|
221
|
+
:sslmode => opts[:sslmode],
|
|
222
|
+
:sslrootcert => opts[:sslrootcert]
|
|
251
223
|
}.delete_if { |key, value| blank_object?(value) }
|
|
252
224
|
connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
|
|
253
225
|
conn = Adapter.connect(connection_params)
|
|
@@ -258,6 +230,10 @@ module Sequel
|
|
|
258
230
|
conn.set_notice_receiver(&receiver)
|
|
259
231
|
end
|
|
260
232
|
else
|
|
233
|
+
unless typecast_value_boolean(@opts.fetch(:force_standard_strings, Postgres.instance_variable_get(:@force_standard_strings))) # , true)) # SEQUEL5
|
|
234
|
+
raise Error, "Cannot create connection using postgres-pr unless force_standard_strings is set"
|
|
235
|
+
end
|
|
236
|
+
|
|
261
237
|
conn = Adapter.connect(
|
|
262
238
|
(opts[:host] unless blank_object?(opts[:host])),
|
|
263
239
|
opts[:port] || 5432,
|
|
@@ -311,7 +287,7 @@ module Sequel
|
|
|
311
287
|
end
|
|
312
288
|
end
|
|
313
289
|
end
|
|
314
|
-
|
|
290
|
+
add_conversion_proc(1082, pr)
|
|
315
291
|
end
|
|
316
292
|
|
|
317
293
|
# Disconnect given connection
|
|
@@ -390,8 +366,12 @@ module Sequel
|
|
|
390
366
|
b << buf while buf = conn.get_copy_data
|
|
391
367
|
b
|
|
392
368
|
end
|
|
369
|
+
rescue => e
|
|
370
|
+
raise_error(e, :disconnect=>true)
|
|
393
371
|
ensure
|
|
394
|
-
|
|
372
|
+
if buf && !e
|
|
373
|
+
raise DatabaseDisconnectError, "disconnecting as a partial COPY may leave the connection in an unusable state"
|
|
374
|
+
end
|
|
395
375
|
end
|
|
396
376
|
end
|
|
397
377
|
end
|
|
@@ -544,10 +524,10 @@ module Sequel
|
|
|
544
524
|
# Add the primary_keys and primary_key_sequences instance variables,
|
|
545
525
|
# so we can get the correct return values for inserted rows.
|
|
546
526
|
def adapter_initialize
|
|
547
|
-
@use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.use_iso_date_format))
|
|
527
|
+
@use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.instance_variable_get(:@use_iso_date_format))) # , true)) # SEQUEL5
|
|
548
528
|
initialize_postgres_adapter
|
|
549
|
-
|
|
550
|
-
|
|
529
|
+
add_conversion_proc(17, method(:unescape_bytea)) if USES_PG
|
|
530
|
+
add_conversion_proc(1082, TYPE_TRANSLATOR.method(:date)) if @use_iso_date_format
|
|
551
531
|
self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
|
|
552
532
|
end
|
|
553
533
|
|
|
@@ -556,7 +536,7 @@ module Sequel
|
|
|
556
536
|
begin
|
|
557
537
|
yield
|
|
558
538
|
rescue => e
|
|
559
|
-
raise_error(e, :classes=>
|
|
539
|
+
raise_error(e, :classes=>database_error_classes)
|
|
560
540
|
end
|
|
561
541
|
end
|
|
562
542
|
|
|
@@ -567,8 +547,15 @@ module Sequel
|
|
|
567
547
|
sqls
|
|
568
548
|
end
|
|
569
549
|
|
|
550
|
+
if USES_PG
|
|
551
|
+
def unescape_bytea(s)
|
|
552
|
+
::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s))
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
DATABASE_ERROR_CLASSES = [PGError].freeze
|
|
570
557
|
def database_error_classes
|
|
571
|
-
|
|
558
|
+
DATABASE_ERROR_CLASSES
|
|
572
559
|
end
|
|
573
560
|
|
|
574
561
|
def disconnect_error?(exception, opts)
|
|
@@ -579,7 +566,7 @@ module Sequel
|
|
|
579
566
|
|
|
580
567
|
def database_exception_sqlstate(exception, opts)
|
|
581
568
|
if exception.respond_to?(:result) && (result = exception.result)
|
|
582
|
-
result.error_field(
|
|
569
|
+
result.error_field(PGresult::PG_DIAG_SQLSTATE)
|
|
583
570
|
end
|
|
584
571
|
end
|
|
585
572
|
|
|
@@ -885,3 +872,4 @@ end
|
|
|
885
872
|
|
|
886
873
|
# SEQUEL5: Remove
|
|
887
874
|
SEQUEL_POSTGRES_USES_PG = Sequel::Postgres::USES_PG
|
|
875
|
+
Sequel::Deprecation.deprecate_constant(Object, :SEQUEL_POSTGRES_USES_PG)
|
|
@@ -6,11 +6,17 @@ module Sequel
|
|
|
6
6
|
module DB2
|
|
7
7
|
Sequel::Database.set_shared_adapter_scheme(:db2, self)
|
|
8
8
|
|
|
9
|
+
# SEQUEL5: Remove
|
|
9
10
|
@use_clob_as_blob = false
|
|
10
|
-
|
|
11
11
|
class << self
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def use_clob_as_blob
|
|
13
|
+
Sequel::Deprecation.deprecate("Sequel::DB2.use_clob_as_blob", "Call this method on the Database instance")
|
|
14
|
+
@use_clob_as_blob
|
|
15
|
+
end
|
|
16
|
+
def use_clob_as_blob=(v)
|
|
17
|
+
Sequel::Deprecation.deprecate("Sequel::DB2.use_clob_as_blob=", "Call this method on the Database instance")
|
|
18
|
+
@use_clob_as_blob = v
|
|
19
|
+
end
|
|
14
20
|
end
|
|
15
21
|
|
|
16
22
|
module DatabaseMethods
|
|
@@ -21,6 +27,16 @@ module Sequel
|
|
|
21
27
|
NULL = ''.freeze
|
|
22
28
|
Sequel::Deprecation.deprecate_constant(self, :NULL)
|
|
23
29
|
|
|
30
|
+
# Whether to use clob as the generic File type, false by default.
|
|
31
|
+
#attr_accessor :use_clob_as_blob # SEQUEL5
|
|
32
|
+
|
|
33
|
+
# SEQUEL5: Remove
|
|
34
|
+
attr_writer :use_clob_as_blob
|
|
35
|
+
def use_clob_as_blob
|
|
36
|
+
v = @use_clob_as_blob
|
|
37
|
+
v.nil? ? Sequel::DB2.instance_variable_get(:@use_clob_as_blob) : v
|
|
38
|
+
end
|
|
39
|
+
|
|
24
40
|
# DB2 always uses :db2 as it's database type
|
|
25
41
|
def database_type
|
|
26
42
|
:db2
|
|
@@ -250,7 +266,7 @@ module Sequel
|
|
|
250
266
|
|
|
251
267
|
# Treat clob as blob if use_clob_as_blob is true
|
|
252
268
|
def schema_column_type(db_type)
|
|
253
|
-
(
|
|
269
|
+
(use_clob_as_blob && db_type.downcase == 'clob') ? :blob : super
|
|
254
270
|
end
|
|
255
271
|
|
|
256
272
|
# SQL to set the transaction isolation level
|
|
@@ -263,7 +279,7 @@ module Sequel
|
|
|
263
279
|
# use this for blob value:
|
|
264
280
|
# cast(X'fffefdfcfbfa' as blob(2G))
|
|
265
281
|
def type_literal_generic_file(column)
|
|
266
|
-
|
|
282
|
+
use_clob_as_blob ? :clob : :blob
|
|
267
283
|
end
|
|
268
284
|
|
|
269
285
|
# DB2 uses smallint to store booleans.
|
|
@@ -433,7 +449,7 @@ module Sequel
|
|
|
433
449
|
|
|
434
450
|
# DB2 uses a literal hexidecimal number for blob strings
|
|
435
451
|
def literal_blob_append(sql, v)
|
|
436
|
-
if
|
|
452
|
+
if db.use_clob_as_blob
|
|
437
453
|
super
|
|
438
454
|
else
|
|
439
455
|
sql << "BLOB(X'" << v.unpack("H*").first << "')"
|
|
@@ -540,7 +540,6 @@ module Sequel
|
|
|
540
540
|
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}#.freeze # SEQUEL5
|
|
541
541
|
EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}#.freeze # SEQUEL5
|
|
542
542
|
#EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
|
|
543
|
-
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
|
|
544
543
|
LIMIT_ALL = Object.new.freeze
|
|
545
544
|
|
|
546
545
|
BOOL_TRUE = '1'.freeze
|
|
@@ -629,6 +628,8 @@ module Sequel
|
|
|
629
628
|
Sequel::Deprecation.deprecate_constant(self, :ROWS_ONLY)
|
|
630
629
|
FETCH_NEXT = " FETCH NEXT ".freeze
|
|
631
630
|
Sequel::Deprecation.deprecate_constant(self, :FETCH_NEXT)
|
|
631
|
+
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
|
|
632
|
+
Sequel::Deprecation.deprecate_constant(self, :NON_SQL_OPTIONS)
|
|
632
633
|
|
|
633
634
|
Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
|
|
634
635
|
Dataset.def_sql_method(self, :delete, %w'with delete limit from output from2 where')
|
|
@@ -637,6 +638,7 @@ module Sequel
|
|
|
637
638
|
|
|
638
639
|
# Allow overriding of the mssql_unicode_strings option at the dataset level.
|
|
639
640
|
def mssql_unicode_strings=(v)
|
|
641
|
+
Sequel::Deprecation.deprecate("Dataset#mssql_unicode_strings=", "Switch to using with_mssql_unicode_strings, which returns a modified copy")
|
|
640
642
|
@opts[:mssql_unicode_strings] = v
|
|
641
643
|
end
|
|
642
644
|
|
|
@@ -1048,9 +1050,8 @@ module Sequel
|
|
|
1048
1050
|
is_2008_or_later? ? :values : :union
|
|
1049
1051
|
end
|
|
1050
1052
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
NON_SQL_OPTIONS
|
|
1053
|
+
def non_sql_option?(key)
|
|
1054
|
+
super || key == :disable_insert_output || key == :mssql_unicode_strings
|
|
1054
1055
|
end
|
|
1055
1056
|
|
|
1056
1057
|
def select_into_sql(sql)
|
|
@@ -12,32 +12,54 @@ module Sequel
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# SEQUEL5: Remove
|
|
15
16
|
@convert_tinyint_to_bool = true
|
|
16
|
-
|
|
17
|
+
@default_charset = nil
|
|
18
|
+
@default_collate = nil
|
|
19
|
+
@default_engine = nil
|
|
17
20
|
class << self
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def convert_tinyint_to_bool
|
|
22
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.convert_tinyint_to_bool", "Call this method on the Database instance")
|
|
23
|
+
@convert_tinyint_to_bool
|
|
24
|
+
end
|
|
25
|
+
def convert_tinyint_to_bool=(v)
|
|
26
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.convert_tinyint_to_bool=", "Call this method on the Database instance")
|
|
27
|
+
@convert_tinyint_to_bool = v
|
|
28
|
+
end
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
def default_charset
|
|
31
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_charset", "Call this method on the Database instance")
|
|
32
|
+
@default_charset
|
|
33
|
+
end
|
|
34
|
+
def default_charset=(v)
|
|
35
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_charset=", "Call this method on the Database instance")
|
|
36
|
+
@default_charset = v
|
|
37
|
+
end
|
|
27
38
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
def default_collate
|
|
40
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_collate", "Call this method on the Database instance")
|
|
41
|
+
@default_collate
|
|
42
|
+
end
|
|
43
|
+
def default_collate=(v)
|
|
44
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_collate=", "Call this method on the Database instance")
|
|
45
|
+
@default_collate = v
|
|
46
|
+
end
|
|
31
47
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
def default_engine
|
|
49
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_engine", "Call this method on the Database instance")
|
|
50
|
+
@default_engine
|
|
51
|
+
end
|
|
52
|
+
def default_engine=(v)
|
|
53
|
+
Sequel::Deprecation.deprecate("Sequel::MySQL.default_engine=", "Call this method on the Database instance")
|
|
54
|
+
@default_engine = v
|
|
55
|
+
end
|
|
35
56
|
end
|
|
36
57
|
|
|
37
58
|
# Methods shared by Database instances that connect to MySQL,
|
|
38
59
|
# currently supported by the native and JDBC adapters.
|
|
39
60
|
module DatabaseMethods
|
|
40
61
|
include UnmodifiedIdentifiers::DatabaseMethods
|
|
62
|
+
include Sequel::Database::SplitAlterTable
|
|
41
63
|
|
|
42
64
|
AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
|
|
43
65
|
Sequel::Deprecation.deprecate_constant(self, :AUTO_INCREMENT)
|
|
@@ -49,8 +71,36 @@ module Sequel
|
|
|
49
71
|
CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}#.freeze # SEQUEL5
|
|
50
72
|
COLUMN_DEFINITION_ORDER = [:collate, :null, :default, :unique, :primary_key, :auto_increment, :references]#.freeze # SEQUEL5
|
|
51
73
|
|
|
52
|
-
include Sequel::Database::SplitAlterTable
|
|
53
74
|
|
|
75
|
+
# Set the default charset used for CREATE TABLE. You can pass the
|
|
76
|
+
# :charset option to create_table to override this setting.
|
|
77
|
+
#attr_accessor :default_charset # SEQUEL5
|
|
78
|
+
|
|
79
|
+
# Set the default collation used for CREATE TABLE. You can pass the
|
|
80
|
+
# :collate option to create_table to override this setting.
|
|
81
|
+
#attr_accessor :default_collate # SEQUEL5
|
|
82
|
+
|
|
83
|
+
# Set the default engine used for CREATE TABLE. You can pass the
|
|
84
|
+
# :engine option to create_table to override this setting.
|
|
85
|
+
#attr_accessor :default_engine # SEQUEL5
|
|
86
|
+
|
|
87
|
+
# SEQUEL5: Remove
|
|
88
|
+
attr_writer :default_charset
|
|
89
|
+
def default_charset
|
|
90
|
+
v = @default_charset
|
|
91
|
+
v.nil? ? Sequel::MySQL.instance_variable_get(:@default_charset) : v
|
|
92
|
+
end
|
|
93
|
+
attr_writer :default_collate
|
|
94
|
+
def default_collate
|
|
95
|
+
v = @default_collate
|
|
96
|
+
v.nil? ? Sequel::MySQL.instance_variable_get(:@default_collate) : v
|
|
97
|
+
end
|
|
98
|
+
attr_writer :default_engine
|
|
99
|
+
def default_engine
|
|
100
|
+
v = @default_engine
|
|
101
|
+
v.nil? ? Sequel::MySQL.instance_variable_get(:@default_engine) : v
|
|
102
|
+
end
|
|
103
|
+
|
|
54
104
|
# MySQL's cast rules are restrictive in that you can't just cast to any possible
|
|
55
105
|
# database type.
|
|
56
106
|
def cast_type_literal(type)
|
|
@@ -375,9 +425,9 @@ module Sequel
|
|
|
375
425
|
|
|
376
426
|
# Use MySQL specific syntax for engine type and character encoding
|
|
377
427
|
def create_table_sql(name, generator, options = OPTS)
|
|
378
|
-
engine = options.fetch(:engine,
|
|
379
|
-
charset = options.fetch(:charset,
|
|
380
|
-
collate = options.fetch(:collate,
|
|
428
|
+
engine = options.fetch(:engine, default_engine)
|
|
429
|
+
charset = options.fetch(:charset, default_charset)
|
|
430
|
+
collate = options.fetch(:collate, default_collate)
|
|
381
431
|
generator.constraints.sort_by{|c| (c[:type] == :primary_key) ? -1 : 1}
|
|
382
432
|
|
|
383
433
|
# Proc for figuring out the primary key for a given table.
|
|
@@ -669,10 +719,11 @@ module Sequel
|
|
|
669
719
|
Sequel::Deprecation.deprecate_constant(self, :CURRENT_TIMESTAMP_56)
|
|
670
720
|
ONLY_OFFSET = ",18446744073709551615".freeze
|
|
671
721
|
Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
|
|
722
|
+
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:insert_ignore, :update_ignore, :on_duplicate_key_update]).freeze
|
|
723
|
+
Sequel::Deprecation.deprecate_constant(self, :NON_SQL_OPTIONS)
|
|
672
724
|
|
|
673
725
|
MATCH_AGAINST = ["MATCH ".freeze, " AGAINST (".freeze, ")".freeze].freeze
|
|
674
726
|
MATCH_AGAINST_BOOLEAN = ["MATCH ".freeze, " AGAINST (".freeze, " IN BOOLEAN MODE)".freeze].freeze
|
|
675
|
-
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:insert_ignore, :update_ignore, :on_duplicate_key_update]).freeze
|
|
676
727
|
|
|
677
728
|
Dataset.def_sql_method(self, :delete, %w'delete from where order limit')
|
|
678
729
|
Dataset.def_sql_method(self, :insert, %w'insert ignore into columns values on_duplicate_key_update')
|
|
@@ -790,8 +841,11 @@ module Sequel
|
|
|
790
841
|
# Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
|
|
791
842
|
# Raises an error on use of :full_outer type, since MySQL doesn't support it.
|
|
792
843
|
def join_table(type, table, expr=nil, opts=OPTS, &block)
|
|
793
|
-
|
|
794
|
-
|
|
844
|
+
if (type == :cross) && !expr.nil?
|
|
845
|
+
Sequel::Deprecation.deprecate(":cross join type with conditions being converted to INNER JOIN on MySQL", "Use :inner join type instead")
|
|
846
|
+
type = :inner
|
|
847
|
+
end
|
|
848
|
+
raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN or NATURAL FULL JOIN") if type == :full_outer || type == :natural_full
|
|
795
849
|
super(type, table, expr, opts, &block)
|
|
796
850
|
end
|
|
797
851
|
|
|
@@ -802,6 +856,7 @@ module Sequel
|
|
|
802
856
|
when :straight
|
|
803
857
|
'STRAIGHT_JOIN'
|
|
804
858
|
when :natural_inner
|
|
859
|
+
Sequel::Deprecation.deprecate(":natural_inner join type being converted to NATURAL LEFT JOIN on MySQL", "Use :natural_left join type for NATURAL LEFT JOIN, or :natural join type for NATURAL JOIN")
|
|
805
860
|
'NATURAL LEFT JOIN'
|
|
806
861
|
else
|
|
807
862
|
super
|
|
@@ -1055,9 +1110,8 @@ module Sequel
|
|
|
1055
1110
|
:values
|
|
1056
1111
|
end
|
|
1057
1112
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
NON_SQL_OPTIONS
|
|
1113
|
+
def non_sql_option?(key)
|
|
1114
|
+
super || key == :insert_ignore || key == :update_ignore || key == :on_duplicate_key_update
|
|
1061
1115
|
end
|
|
1062
1116
|
|
|
1063
1117
|
def select_only_offset_sql(sql)
|
|
@@ -348,7 +348,7 @@ module Sequel
|
|
|
348
348
|
Sequel::Deprecation.deprecate_constant(self, :SKIP_LOCKED)
|
|
349
349
|
|
|
350
350
|
include(Module.new do
|
|
351
|
-
Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order lock')
|
|
351
|
+
Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order limit lock')
|
|
352
352
|
end)
|
|
353
353
|
|
|
354
354
|
def complex_expression_sql_append(sql, op, args)
|
|
@@ -421,7 +421,10 @@ module Sequel
|
|
|
421
421
|
# Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
|
|
422
422
|
def select_sql
|
|
423
423
|
return super if @opts[:sql]
|
|
424
|
-
|
|
424
|
+
return super if supports_fetch_next_rows?
|
|
425
|
+
|
|
426
|
+
o = @opts[:offset]
|
|
427
|
+
if o && o != 0
|
|
425
428
|
columns = clone(:append_sql=>String.new, :placeholder_literal_null=>true).columns
|
|
426
429
|
dsa1 = dataset_alias(1)
|
|
427
430
|
rn = row_number_column
|
|
@@ -437,7 +440,7 @@ module Sequel
|
|
|
437
440
|
subselect_sql_append(sql, ds)
|
|
438
441
|
sql
|
|
439
442
|
elsif limit = @opts[:limit]
|
|
440
|
-
ds =
|
|
443
|
+
ds = unlimited
|
|
441
444
|
# Lock doesn't work in subselects, so don't use a subselect when locking.
|
|
442
445
|
# Don't use a subselect if custom SQL is used, as it breaks somethings.
|
|
443
446
|
ds = ds.from_self unless @opts[:lock]
|
|
@@ -449,6 +452,21 @@ module Sequel
|
|
|
449
452
|
end
|
|
450
453
|
end
|
|
451
454
|
|
|
455
|
+
def select_limit_sql(sql)
|
|
456
|
+
return unless supports_fetch_next_rows?
|
|
457
|
+
|
|
458
|
+
if offset = @opts[:offset]
|
|
459
|
+
sql << " OFFSET "
|
|
460
|
+
literal_append(sql, offset)
|
|
461
|
+
sql << " ROWS"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
if limit = @opts[:limit]
|
|
465
|
+
sql << " FETCH NEXT "
|
|
466
|
+
literal_append(sql, limit)
|
|
467
|
+
sql << " ROWS ONLY"
|
|
468
|
+
end
|
|
469
|
+
end
|
|
452
470
|
# Oracle requires recursive CTEs to have column aliases.
|
|
453
471
|
def recursive_cte_requires_column_aliases?
|
|
454
472
|
true
|
|
@@ -463,6 +481,11 @@ module Sequel
|
|
|
463
481
|
false
|
|
464
482
|
end
|
|
465
483
|
|
|
484
|
+
# Oracle supports FETCH NEXT ROWS since 12c
|
|
485
|
+
def supports_fetch_next_rows?
|
|
486
|
+
server_version >= 12000000 && !(@opts[:lock] || @opts[:skip_locked])
|
|
487
|
+
end
|
|
488
|
+
|
|
466
489
|
# Oracle supports GROUP BY CUBE
|
|
467
490
|
def supports_group_cube?
|
|
468
491
|
true
|