sequel 4.45.0 → 4.46.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 +108 -0
- data/doc/release_notes/4.46.0.txt +404 -0
- data/doc/security.rdoc +9 -0
- data/doc/sql.rdoc +2 -2
- data/doc/testing.rdoc +1 -1
- data/doc/validations.rdoc +1 -2
- data/lib/sequel/adapters/ado.rb +8 -3
- data/lib/sequel/adapters/ado/access.rb +8 -4
- data/lib/sequel/adapters/ado/mssql.rb +3 -1
- data/lib/sequel/adapters/amalgalite.rb +5 -0
- data/lib/sequel/adapters/cubrid.rb +16 -7
- data/lib/sequel/adapters/do.rb +7 -1
- data/lib/sequel/adapters/do/mysql.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +10 -5
- data/lib/sequel/adapters/jdbc.rb +8 -2
- data/lib/sequel/adapters/jdbc/as400.rb +10 -3
- data/lib/sequel/adapters/jdbc/db2.rb +27 -16
- data/lib/sequel/adapters/jdbc/derby.rb +47 -20
- data/lib/sequel/adapters/jdbc/h2.rb +13 -7
- data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +6 -1
- data/lib/sequel/adapters/odbc.rb +20 -8
- data/lib/sequel/adapters/odbc/mssql.rb +6 -3
- data/lib/sequel/adapters/oracle.rb +12 -6
- data/lib/sequel/adapters/postgres.rb +20 -8
- data/lib/sequel/adapters/shared/access.rb +76 -47
- data/lib/sequel/adapters/shared/cubrid.rb +16 -11
- data/lib/sequel/adapters/shared/db2.rb +46 -19
- data/lib/sequel/adapters/shared/firebird.rb +20 -8
- data/lib/sequel/adapters/shared/informix.rb +6 -3
- data/lib/sequel/adapters/shared/mssql.rb +132 -72
- data/lib/sequel/adapters/shared/mysql.rb +112 -65
- data/lib/sequel/adapters/shared/oracle.rb +36 -21
- data/lib/sequel/adapters/shared/postgres.rb +91 -56
- data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
- data/lib/sequel/adapters/shared/sqlite.rb +67 -32
- data/lib/sequel/adapters/sqlanywhere.rb +9 -1
- data/lib/sequel/adapters/sqlite.rb +8 -1
- data/lib/sequel/adapters/swift.rb +5 -0
- data/lib/sequel/adapters/swift/mysql.rb +4 -2
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +10 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/adapters/utils/pg_types.rb +14 -6
- data/lib/sequel/adapters/utils/replace.rb +4 -2
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/core.rb +24 -11
- data/lib/sequel/database/connecting.rb +9 -3
- data/lib/sequel/database/dataset_defaults.rb +7 -1
- data/lib/sequel/database/logging.rb +1 -0
- data/lib/sequel/database/misc.rb +5 -2
- data/lib/sequel/database/query.rb +7 -5
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +50 -27
- data/lib/sequel/database/transactions.rb +19 -9
- data/lib/sequel/dataset/actions.rb +15 -6
- data/lib/sequel/dataset/graph.rb +15 -5
- data/lib/sequel/dataset/misc.rb +12 -4
- data/lib/sequel/dataset/mutation.rb +17 -8
- data/lib/sequel/dataset/prepared_statements.rb +3 -2
- data/lib/sequel/dataset/query.rb +84 -38
- data/lib/sequel/dataset/sql.rb +302 -191
- data/lib/sequel/deprecated.rb +26 -17
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/migration.rb +28 -4
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +4 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
- data/lib/sequel/extensions/set_overrides.rb +2 -0
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +11 -7
- data/lib/sequel/model/associations.rb +5 -7
- data/lib/sequel/model/base.rb +47 -45
- data/lib/sequel/model/dataset_module.rb +9 -14
- data/lib/sequel/model/plugins.rb +3 -0
- data/lib/sequel/no_core_ext.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -1
- data/lib/sequel/plugins/boolean_subsets.rb +7 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/finder.rb +240 -0
- data/lib/sequel/plugins/inverted_subsets.rb +19 -12
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
- data/lib/sequel/plugins/subset_conditions.rb +11 -3
- data/lib/sequel/plugins/whitelist_security.rb +118 -0
- data/lib/sequel/sql.rb +80 -36
- data/lib/sequel/timezones.rb +2 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +20 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +12 -8
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +36 -34
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +87 -9
- data/spec/core/dataset_spec.rb +501 -129
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +146 -60
- data/spec/core/mock_adapter_spec.rb +1 -1
- data/spec/core/object_graph_spec.rb +61 -9
- data/spec/core/placeholder_literalizer_spec.rb +20 -2
- data/spec/core/schema_generator_spec.rb +6 -6
- data/spec/core/schema_spec.rb +54 -5
- data/spec/core_extensions_spec.rb +122 -18
- data/spec/deprecation_helper.rb +27 -2
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
- data/spec/extensions/association_proxies_spec.rb +2 -2
- data/spec/extensions/auto_literal_strings_spec.rb +212 -0
- data/spec/extensions/blacklist_security_spec.rb +1 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
- data/spec/extensions/column_select_spec.rb +20 -8
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/core_refinements_spec.rb +29 -12
- data/spec/extensions/dataset_associations_spec.rb +12 -12
- data/spec/extensions/def_dataset_method_spec.rb +100 -0
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +260 -0
- data/spec/extensions/graph_each_spec.rb +2 -2
- data/spec/extensions/identifier_mangling_spec.rb +14 -8
- data/spec/extensions/inverted_subsets_spec.rb +4 -4
- data/spec/extensions/lazy_attributes_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +38 -14
- data/spec/extensions/nested_attributes_spec.rb +18 -6
- data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
- data/spec/extensions/pg_enum_spec.rb +16 -1
- data/spec/extensions/pg_interval_spec.rb +11 -2
- data/spec/extensions/pg_loose_count_spec.rb +5 -0
- data/spec/extensions/pg_row_spec.rb +25 -0
- data/spec/extensions/prepared_statements_spec.rb +10 -1
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/set_overrides_spec.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +0 -1
- data/spec/extensions/subset_conditions_spec.rb +6 -6
- data/spec/extensions/table_select_spec.rb +24 -12
- data/spec/extensions/to_dot_spec.rb +4 -4
- data/spec/extensions/whitelist_security_spec.rb +131 -0
- data/spec/integration/dataset_test.rb +9 -5
- data/spec/integration/model_test.rb +2 -0
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/model/associations_spec.rb +39 -11
- data/spec/model/base_spec.rb +44 -24
- data/spec/model/class_dataset_methods_spec.rb +18 -16
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +84 -24
- data/spec/model/model_spec.rb +97 -63
- data/spec/model/record_spec.rb +21 -13
- metadata +13 -2
|
@@ -67,7 +67,7 @@ module Sequel
|
|
|
67
67
|
attr_accessor :force_standard_strings
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
class CreateTableGenerator < Sequel::Schema::
|
|
70
|
+
class CreateTableGenerator < Sequel::Schema::CreateTableGenerator
|
|
71
71
|
# Add an exclusion constraint when creating the table. Elements should be
|
|
72
72
|
# an array of 2 element arrays, with the first element being the column or
|
|
73
73
|
# expression the exclusion constraint is applied to, and the second element
|
|
@@ -111,14 +111,17 @@ module Sequel
|
|
|
111
111
|
module DatabaseMethods
|
|
112
112
|
include UnmodifiedIdentifiers::DatabaseMethods
|
|
113
113
|
|
|
114
|
-
PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
|
|
115
114
|
RE_CURRVAL_ERROR = /currval of sequence "(.*)" is not yet defined in this session|relation "(.*)" does not exist/.freeze
|
|
116
|
-
|
|
115
|
+
Sequel::Deprecation.deprecate_constant(self, :RE_CURRVAL_ERROR)
|
|
117
116
|
POSTGRES_DEFAULT_RE = /\A(?:B?('.*')::[^']+|\((-?\d+(?:\.\d+)?)\))\z/
|
|
117
|
+
Sequel::Deprecation.deprecate_constant(self, :POSTGRES_DEFAULT_RE)
|
|
118
118
|
UNLOGGED = 'UNLOGGED '.freeze
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
Sequel::Deprecation.deprecate_constant(self, :UNLOGGED)
|
|
120
|
+
|
|
121
|
+
PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
|
|
122
|
+
FOREIGN_KEY_LIST_ON_DELETE_MAP = {'a'=>:no_action, 'r'=>:restrict, 'c'=>:cascade, 'n'=>:set_null, 'd'=>:set_default}.freeze
|
|
123
|
+
ON_COMMIT = {:drop => 'DROP', :delete_rows => 'DELETE ROWS', :preserve_rows => 'PRESERVE ROWS'}.freeze
|
|
124
|
+
#ON_COMMIT.each_value(&:freeze) # SEQUEL5
|
|
122
125
|
|
|
123
126
|
# SQL fragment for custom sequences (ones not created by serial primary key),
|
|
124
127
|
# Returning the schema and literal form of the sequence name, by parsing
|
|
@@ -183,7 +186,7 @@ module Sequel
|
|
|
183
186
|
# the conversion proc is looked up in the PG_NAMED_TYPES hash.
|
|
184
187
|
def add_named_conversion_proc(name, &block)
|
|
185
188
|
unless block
|
|
186
|
-
if block =
|
|
189
|
+
if block = PG_NAMED__TYPES[name]
|
|
187
190
|
Sequel::Deprecation.deprecate("Sequel::PG_NAMED_TYPES", "Call Database#add_named_conversion_proc directly for each database you want to support the #{name} type")
|
|
188
191
|
end
|
|
189
192
|
end
|
|
@@ -698,7 +701,7 @@ module Sequel
|
|
|
698
701
|
|
|
699
702
|
# Handle PostgreSQL specific default format.
|
|
700
703
|
def column_schema_normalize_default(default, type)
|
|
701
|
-
if m =
|
|
704
|
+
if m = /\A(?:B?('.*')::[^']+|\((-?\d+(?:\.\d+)?)\))\z/.match(default)
|
|
702
705
|
default = m[1] || m[2]
|
|
703
706
|
end
|
|
704
707
|
super(default, type)
|
|
@@ -795,11 +798,13 @@ module Sequel
|
|
|
795
798
|
end
|
|
796
799
|
|
|
797
800
|
EXCLUSION_CONSTRAINT_SQL_STATE = '23P01'.freeze
|
|
801
|
+
Sequel::Deprecation.deprecate_constant(self, :EXCLUSION_CONSTRAINT_SQL_STATE)
|
|
798
802
|
DEADLOCK_SQL_STATE = '40P01'.freeze
|
|
803
|
+
Sequel::Deprecation.deprecate_constant(self, :DEADLOCK_SQL_STATE)
|
|
799
804
|
def database_specific_error_class_from_sqlstate(sqlstate)
|
|
800
|
-
if sqlstate ==
|
|
805
|
+
if sqlstate == '23P01'
|
|
801
806
|
ExclusionConstraintViolation
|
|
802
|
-
elsif sqlstate ==
|
|
807
|
+
elsif sqlstate == '40P01'
|
|
803
808
|
SerializationFailure
|
|
804
809
|
else
|
|
805
810
|
super
|
|
@@ -900,7 +905,7 @@ module Sequel
|
|
|
900
905
|
raise(Error, "can't provide both :foreign and :unlogged to create_table") if options[:unlogged]
|
|
901
906
|
'FOREIGN '
|
|
902
907
|
elsif options[:unlogged]
|
|
903
|
-
UNLOGGED
|
|
908
|
+
'UNLOGGED '
|
|
904
909
|
end
|
|
905
910
|
|
|
906
911
|
"CREATE #{prefix_sql}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)}"
|
|
@@ -1014,10 +1019,10 @@ module Sequel
|
|
|
1014
1019
|
def get_conversion_procs
|
|
1015
1020
|
procs = PG_TYPES.dup
|
|
1016
1021
|
procs[1184] = procs[1114] = method(:to_application_timestamp)
|
|
1017
|
-
unless
|
|
1018
|
-
Sequel::Deprecation.deprecate("Sequel::PG_NAMED_TYPES", "Call Database#add_named_conversion_proc directly for each Database instance where you want to support the following type(s): #{
|
|
1022
|
+
unless PG_NAMED__TYPES.empty?
|
|
1023
|
+
Sequel::Deprecation.deprecate("Sequel::PG_NAMED_TYPES", "Call Database#add_named_conversion_proc directly for each Database instance where you want to support the following type(s): #{PG_NAMED__TYPES.keys.join(', ')}")
|
|
1019
1024
|
end
|
|
1020
|
-
add_named_conversion_procs(procs,
|
|
1025
|
+
add_named_conversion_procs(procs, PG_NAMED__TYPES)
|
|
1021
1026
|
procs
|
|
1022
1027
|
end
|
|
1023
1028
|
|
|
@@ -1236,43 +1241,71 @@ module Sequel
|
|
|
1236
1241
|
include UnmodifiedIdentifiers::DatasetMethods
|
|
1237
1242
|
|
|
1238
1243
|
ACCESS_SHARE = 'ACCESS SHARE'.freeze
|
|
1244
|
+
Sequel::Deprecation.deprecate_constant(self, :ACCESS_SHARE)
|
|
1239
1245
|
ACCESS_EXCLUSIVE = 'ACCESS EXCLUSIVE'.freeze
|
|
1246
|
+
Sequel::Deprecation.deprecate_constant(self, :ACCESS_EXCLUSIVE)
|
|
1240
1247
|
BOOL_FALSE = 'false'.freeze
|
|
1248
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
1241
1249
|
BOOL_TRUE = 'true'.freeze
|
|
1250
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
1242
1251
|
COMMA_SEPARATOR = ', '.freeze
|
|
1252
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA_SEPARATOR)
|
|
1243
1253
|
EXCLUSIVE = 'EXCLUSIVE'.freeze
|
|
1254
|
+
Sequel::Deprecation.deprecate_constant(self, :EXCLUSIVE)
|
|
1244
1255
|
EXPLAIN = 'EXPLAIN '.freeze
|
|
1256
|
+
Sequel::Deprecation.deprecate_constant(self, :EXPLAIN)
|
|
1245
1257
|
EXPLAIN_ANALYZE = 'EXPLAIN ANALYZE '.freeze
|
|
1258
|
+
Sequel::Deprecation.deprecate_constant(self, :EXPLAIN_ANALYZE)
|
|
1246
1259
|
FOR_SHARE = ' FOR SHARE'.freeze
|
|
1247
|
-
|
|
1260
|
+
Sequel::Deprecation.deprecate_constant(self, :FOR_SHARE)
|
|
1248
1261
|
PG_TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S".freeze
|
|
1262
|
+
Sequel::Deprecation.deprecate_constant(self, :PG_TIMESTAMP_FORMAT)
|
|
1249
1263
|
QUERY_PLAN = 'QUERY PLAN'.to_sym
|
|
1264
|
+
Sequel::Deprecation.deprecate_constant(self, :QUERY_PLAN)
|
|
1250
1265
|
ROW_EXCLUSIVE = 'ROW EXCLUSIVE'.freeze
|
|
1266
|
+
Sequel::Deprecation.deprecate_constant(self, :ROW_EXCLUSIVE)
|
|
1251
1267
|
ROW_SHARE = 'ROW SHARE'.freeze
|
|
1268
|
+
Sequel::Deprecation.deprecate_constant(self, :ROW_SHARE)
|
|
1252
1269
|
SHARE = 'SHARE'.freeze
|
|
1270
|
+
Sequel::Deprecation.deprecate_constant(self, :SHARE)
|
|
1253
1271
|
SHARE_ROW_EXCLUSIVE = 'SHARE ROW EXCLUSIVE'.freeze
|
|
1272
|
+
Sequel::Deprecation.deprecate_constant(self, :SHARE_ROW_EXCLUSIVE)
|
|
1254
1273
|
SHARE_UPDATE_EXCLUSIVE = 'SHARE UPDATE EXCLUSIVE'.freeze
|
|
1274
|
+
Sequel::Deprecation.deprecate_constant(self, :SHARE_UPDATE_EXCLUSIVE)
|
|
1255
1275
|
SQL_WITH_RECURSIVE = "WITH RECURSIVE ".freeze
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1276
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_WITH_RECURSIVE)
|
|
1277
|
+
SPACE = ' '.freeze
|
|
1278
|
+
Sequel::Deprecation.deprecate_constant(self, :SPACE)
|
|
1279
|
+
FROM = ' FROM '.freeze
|
|
1280
|
+
Sequel::Deprecation.deprecate_constant(self, :FROM)
|
|
1281
|
+
APOS = "'".freeze
|
|
1282
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
1283
|
+
APOS_RE = /'/.freeze
|
|
1284
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS_RE)
|
|
1285
|
+
DOUBLE_APOS = "''".freeze
|
|
1286
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_APOS)
|
|
1287
|
+
PAREN_CLOSE = ')'.freeze
|
|
1288
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
|
|
1289
|
+
PAREN_OPEN = '('.freeze
|
|
1290
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_OPEN)
|
|
1291
|
+
COMMA = ', '.freeze
|
|
1292
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
1293
|
+
ESCAPE = " ESCAPE ".freeze
|
|
1294
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE)
|
|
1295
|
+
BACKSLASH = "\\".freeze
|
|
1296
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKSLASH)
|
|
1297
|
+
AS = ' AS '.freeze
|
|
1298
|
+
Sequel::Deprecation.deprecate_constant(self, :AS)
|
|
1267
1299
|
XOR_OP = ' # '.freeze
|
|
1268
1300
|
CRLF = "\r\n".freeze
|
|
1269
1301
|
BLOB_RE = /[\000-\037\047\134\177-\377]/n.freeze
|
|
1270
1302
|
WINDOW = " WINDOW ".freeze
|
|
1271
1303
|
SELECT_VALUES = "VALUES ".freeze
|
|
1272
1304
|
EMPTY_STRING = ''.freeze
|
|
1273
|
-
LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)
|
|
1274
1305
|
SKIP_LOCKED = " SKIP LOCKED".freeze
|
|
1275
1306
|
|
|
1307
|
+
NULL = LiteralString.new('NULL').freeze
|
|
1308
|
+
LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze)
|
|
1276
1309
|
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:cursor, :insert_conflict]).freeze
|
|
1277
1310
|
|
|
1278
1311
|
Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
|
|
@@ -1291,7 +1324,7 @@ module Sequel
|
|
|
1291
1324
|
def complex_expression_sql_append(sql, op, args)
|
|
1292
1325
|
case op
|
|
1293
1326
|
when :^
|
|
1294
|
-
j =
|
|
1327
|
+
j = ' # '
|
|
1295
1328
|
c = false
|
|
1296
1329
|
args.each do |a|
|
|
1297
1330
|
sql << j if c
|
|
@@ -1299,13 +1332,13 @@ module Sequel
|
|
|
1299
1332
|
c ||= true
|
|
1300
1333
|
end
|
|
1301
1334
|
when :ILIKE, :'NOT ILIKE'
|
|
1302
|
-
sql <<
|
|
1303
|
-
literal_append(sql, args
|
|
1304
|
-
sql <<
|
|
1305
|
-
literal_append(sql, args
|
|
1306
|
-
sql << ESCAPE
|
|
1307
|
-
literal_append(sql,
|
|
1308
|
-
sql <<
|
|
1335
|
+
sql << '('
|
|
1336
|
+
literal_append(sql, args[0])
|
|
1337
|
+
sql << ' ' << op.to_s << ' '
|
|
1338
|
+
literal_append(sql, args[1])
|
|
1339
|
+
sql << " ESCAPE "
|
|
1340
|
+
literal_append(sql, "\\")
|
|
1341
|
+
sql << ')'
|
|
1309
1342
|
else
|
|
1310
1343
|
super
|
|
1311
1344
|
end
|
|
@@ -1331,7 +1364,7 @@ module Sequel
|
|
|
1331
1364
|
|
|
1332
1365
|
# Return the results of an EXPLAIN query as a string
|
|
1333
1366
|
def explain(opts=OPTS)
|
|
1334
|
-
with_sql((opts[:analyze] ?
|
|
1367
|
+
with_sql((opts[:analyze] ? 'EXPLAIN ANALYZE ' : 'EXPLAIN ') + select_sql).map(:'QUERY PLAN').join("\r\n")
|
|
1335
1368
|
end
|
|
1336
1369
|
|
|
1337
1370
|
# Return a cloned dataset which will use FOR SHARE to lock returned rows.
|
|
@@ -1379,7 +1412,7 @@ module Sequel
|
|
|
1379
1412
|
terms = Sequel.function(query_func, lang, phrase_terms)
|
|
1380
1413
|
end
|
|
1381
1414
|
|
|
1382
|
-
ds = where(Sequel.lit(["
|
|
1415
|
+
ds = where(Sequel.lit(["", " @@ ", ""], cols, terms))
|
|
1383
1416
|
|
|
1384
1417
|
if opts[:phrase]
|
|
1385
1418
|
raise Error, "can't use :phrase with either :tsvector or :tsquery arguments to full_text_search together" if opts[:tsvector] || opts[:tsquery]
|
|
@@ -1600,7 +1633,9 @@ module Sequel
|
|
|
1600
1633
|
end
|
|
1601
1634
|
end
|
|
1602
1635
|
|
|
1603
|
-
# Return a clone of the dataset with an addition named window that can be
|
|
1636
|
+
# Return a clone of the dataset with an addition named window that can be
|
|
1637
|
+
# referenced in window functions. See {SQL::Window} for a list of options
|
|
1638
|
+
# that can be passed in.
|
|
1604
1639
|
def window(name, opts)
|
|
1605
1640
|
clone(:window=>(@opts[:window]||[]) + [[name, SQL::Window.new(opts)]])
|
|
1606
1641
|
end
|
|
@@ -1640,7 +1675,7 @@ module Sequel
|
|
|
1640
1675
|
|
|
1641
1676
|
# Only include the primary table in the main delete clause
|
|
1642
1677
|
def delete_from_sql(sql)
|
|
1643
|
-
sql << FROM
|
|
1678
|
+
sql << ' FROM '
|
|
1644
1679
|
source_list_append(sql, @opts[:from][0..0])
|
|
1645
1680
|
end
|
|
1646
1681
|
|
|
@@ -1697,7 +1732,7 @@ module Sequel
|
|
|
1697
1732
|
if(from = @opts[:from][1..-1]).empty?
|
|
1698
1733
|
raise(Error, 'Need multiple FROM tables if updating/deleting a dataset with JOINs') if @opts[:join]
|
|
1699
1734
|
else
|
|
1700
|
-
sql <<
|
|
1735
|
+
sql << ' ' << type.to_s << ' '
|
|
1701
1736
|
source_list_append(sql, from)
|
|
1702
1737
|
select_join_sql(sql)
|
|
1703
1738
|
end
|
|
@@ -1705,12 +1740,12 @@ module Sequel
|
|
|
1705
1740
|
|
|
1706
1741
|
# Use a generic blob quoting method, hopefully overridden in one of the subadapter methods
|
|
1707
1742
|
def literal_blob_append(sql, v)
|
|
1708
|
-
sql <<
|
|
1743
|
+
sql << "'" << v.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{("%o" % b[0..1].unpack("C")[0]).rjust(3, '0')}"} << "'"
|
|
1709
1744
|
end
|
|
1710
1745
|
|
|
1711
1746
|
# PostgreSQL uses FALSE for false values
|
|
1712
1747
|
def literal_false
|
|
1713
|
-
|
|
1748
|
+
'false'
|
|
1714
1749
|
end
|
|
1715
1750
|
|
|
1716
1751
|
# PostgreSQL quotes NaN and Infinity.
|
|
@@ -1728,12 +1763,12 @@ module Sequel
|
|
|
1728
1763
|
|
|
1729
1764
|
# Assume that SQL standard quoting is on, per Sequel's defaults
|
|
1730
1765
|
def literal_string_append(sql, v)
|
|
1731
|
-
sql <<
|
|
1766
|
+
sql << "'" << v.gsub("'", "''") << "'"
|
|
1732
1767
|
end
|
|
1733
1768
|
|
|
1734
1769
|
# PostgreSQL uses FALSE for false values
|
|
1735
1770
|
def literal_true
|
|
1736
|
-
|
|
1771
|
+
'true'
|
|
1737
1772
|
end
|
|
1738
1773
|
|
|
1739
1774
|
# PostgreSQL supports multiple rows in INSERT.
|
|
@@ -1749,38 +1784,38 @@ module Sequel
|
|
|
1749
1784
|
# PostgreSQL requires parentheses around compound datasets if they use
|
|
1750
1785
|
# CTEs, and using them in other places doesn't hurt.
|
|
1751
1786
|
def compound_dataset_sql_append(sql, ds)
|
|
1752
|
-
sql <<
|
|
1787
|
+
sql << '('
|
|
1753
1788
|
super
|
|
1754
|
-
sql <<
|
|
1789
|
+
sql << ')'
|
|
1755
1790
|
end
|
|
1756
1791
|
|
|
1757
1792
|
# Support FOR SHARE locking when using the :share lock style.
|
|
1758
1793
|
# Use SKIP LOCKED if skipping locked rows.
|
|
1759
1794
|
def select_lock_sql(sql)
|
|
1760
1795
|
if @opts[:lock] == :share
|
|
1761
|
-
sql <<
|
|
1796
|
+
sql << ' FOR SHARE'
|
|
1762
1797
|
else
|
|
1763
1798
|
super
|
|
1764
1799
|
end
|
|
1765
1800
|
|
|
1766
1801
|
if @opts[:skip_locked]
|
|
1767
|
-
sql <<
|
|
1802
|
+
sql << " SKIP LOCKED"
|
|
1768
1803
|
end
|
|
1769
1804
|
end
|
|
1770
1805
|
|
|
1771
1806
|
# Support VALUES clause instead of the SELECT clause to return rows.
|
|
1772
1807
|
def select_values_sql(sql)
|
|
1773
|
-
sql <<
|
|
1808
|
+
sql << "VALUES "
|
|
1774
1809
|
expression_list_append(sql, opts[:values])
|
|
1775
1810
|
end
|
|
1776
1811
|
|
|
1777
1812
|
# SQL fragment for named window specifications
|
|
1778
1813
|
def select_window_sql(sql)
|
|
1779
1814
|
if ws = @opts[:window]
|
|
1780
|
-
sql << WINDOW
|
|
1815
|
+
sql << " WINDOW "
|
|
1781
1816
|
c = false
|
|
1782
|
-
co =
|
|
1783
|
-
as = AS
|
|
1817
|
+
co = ', '
|
|
1818
|
+
as = ' AS '
|
|
1784
1819
|
ws.map do |name, window|
|
|
1785
1820
|
sql << co if c
|
|
1786
1821
|
literal_append(sql, name)
|
|
@@ -1793,7 +1828,7 @@ module Sequel
|
|
|
1793
1828
|
|
|
1794
1829
|
# Use WITH RECURSIVE instead of WITH if any of the CTEs is recursive
|
|
1795
1830
|
def select_with_sql_base
|
|
1796
|
-
opts[:with].any?{|w| w[:recursive]} ?
|
|
1831
|
+
opts[:with].any?{|w| w[:recursive]} ? "WITH RECURSIVE " : super
|
|
1797
1832
|
end
|
|
1798
1833
|
|
|
1799
1834
|
# The version of the database server
|
|
@@ -1816,8 +1851,8 @@ module Sequel
|
|
|
1816
1851
|
|
|
1817
1852
|
# Concatenate the expressions with a space in between
|
|
1818
1853
|
def full_text_string_join(cols)
|
|
1819
|
-
cols = Array(cols).map{|x| SQL::Function.new(:COALESCE, x,
|
|
1820
|
-
cols = cols.zip([
|
|
1854
|
+
cols = Array(cols).map{|x| SQL::Function.new(:COALESCE, x, '')}
|
|
1855
|
+
cols = cols.zip([' '] * cols.length).flatten
|
|
1821
1856
|
cols.pop
|
|
1822
1857
|
SQL::StringExpression.new(:'||', *cols)
|
|
1823
1858
|
end
|
|
@@ -1829,7 +1864,7 @@ module Sequel
|
|
|
1829
1864
|
|
|
1830
1865
|
# Only include the primary table in the main update clause
|
|
1831
1866
|
def update_table_sql(sql)
|
|
1832
|
-
sql <<
|
|
1867
|
+
sql << ' '
|
|
1833
1868
|
source_list_append(sql, @opts[:from][0..0])
|
|
1834
1869
|
end
|
|
1835
1870
|
end
|
|
@@ -19,12 +19,19 @@ module Sequel
|
|
|
19
19
|
attr_writer :convert_smallint_to_bool
|
|
20
20
|
|
|
21
21
|
AUTO_INCREMENT = 'IDENTITY'.freeze
|
|
22
|
+
Sequel::Deprecation.deprecate_constant(self, :AUTO_INCREMENT)
|
|
22
23
|
SQL_BEGIN = "BEGIN TRANSACTION".freeze
|
|
24
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_BEGIN)
|
|
23
25
|
SQL_COMMIT = "COMMIT TRANSACTION".freeze
|
|
26
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_COMMIT)
|
|
24
27
|
SQL_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION".freeze
|
|
28
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_ROLLBACK)
|
|
25
29
|
TEMPORARY = "GLOBAL TEMPORARY ".freeze
|
|
30
|
+
Sequel::Deprecation.deprecate_constant(self, :TEMPORARY)
|
|
26
31
|
SMALLINT_RE = /smallint/i.freeze
|
|
27
|
-
|
|
32
|
+
Sequel::Deprecation.deprecate_constant(self, :SMALLINT_RE)
|
|
33
|
+
DECIMAL_TYPE_RE = /numeric/i
|
|
34
|
+
Sequel::Deprecation.deprecate_constant(self, :DECIMAL_TYPE_RE)
|
|
28
35
|
|
|
29
36
|
# Whether to convert smallint to boolean arguments for this dataset.
|
|
30
37
|
# Defaults to the SqlAnywhere module setting.
|
|
@@ -49,7 +56,7 @@ module Sequel
|
|
|
49
56
|
|
|
50
57
|
# Convert smallint type to boolean if convert_smallint_to_bool is true
|
|
51
58
|
def schema_column_type(db_type)
|
|
52
|
-
if convert_smallint_to_bool && db_type =~
|
|
59
|
+
if convert_smallint_to_bool && db_type =~ /smallint/i
|
|
53
60
|
:boolean
|
|
54
61
|
else
|
|
55
62
|
super
|
|
@@ -67,9 +74,9 @@ module Sequel
|
|
|
67
74
|
auto_increment = row.delete(:is_autoincrement)
|
|
68
75
|
row[:auto_increment] = auto_increment == 1 || auto_increment == true
|
|
69
76
|
row[:primary_key] = row.delete(:pkey) == 'Y'
|
|
70
|
-
row[:allow_null] = row[:nulls_allowed].is_a?(
|
|
77
|
+
row[:allow_null] = row[:nulls_allowed].is_a?(Integer) ? row.delete(:nulls_allowed) == 1 : row.delete(:nulls_allowed)
|
|
71
78
|
row[:db_type] = row.delete(:domain_name)
|
|
72
|
-
row[:type] = if row[:db_type] =~
|
|
79
|
+
row[:type] = if row[:db_type] =~ /numeric/i and (row[:scale].is_a?(Integer) ? row[:scale] == 0 : !row[:scale])
|
|
73
80
|
:integer
|
|
74
81
|
else
|
|
75
82
|
schema_column_type(row[:db_type])
|
|
@@ -114,7 +121,7 @@ module Sequel
|
|
|
114
121
|
si[:colnames].as(:columns),
|
|
115
122
|
fks[:primary_tname].as(:table_name)]}.
|
|
116
123
|
join(Sequel[:sys][:sysforeignkeys].as(:fks), :role => :role).
|
|
117
|
-
join(Sequel[:sys][:sysindexes].as(:si),
|
|
124
|
+
join(Sequel[:sys][:sysindexes].as(:si), {:iname => Sequel[:fk][:role]}, {:implicit_qualifier => :fk}).
|
|
118
125
|
where{{fks[:foreign_tname]=>im.call(table)}}.
|
|
119
126
|
each do |r|
|
|
120
127
|
unless r[:type].downcase == 'primary key'
|
|
@@ -152,7 +159,7 @@ module Sequel
|
|
|
152
159
|
|
|
153
160
|
# Sybase uses the IDENTITY column for autoincrementing columns.
|
|
154
161
|
def auto_increment_sql
|
|
155
|
-
|
|
162
|
+
'IDENTITY'
|
|
156
163
|
end
|
|
157
164
|
|
|
158
165
|
# Sybase does not allow adding primary key constraints to NULLable columns.
|
|
@@ -162,22 +169,22 @@ module Sequel
|
|
|
162
169
|
|
|
163
170
|
# SQL fragment for marking a table as temporary
|
|
164
171
|
def temporary_table_sql
|
|
165
|
-
TEMPORARY
|
|
172
|
+
"GLOBAL TEMPORARY "
|
|
166
173
|
end
|
|
167
174
|
|
|
168
175
|
# SQL to BEGIN a transaction.
|
|
169
176
|
def begin_transaction_sql
|
|
170
|
-
|
|
177
|
+
"BEGIN TRANSACTION"
|
|
171
178
|
end
|
|
172
179
|
|
|
173
180
|
# SQL to ROLLBACK a transaction.
|
|
174
181
|
def rollback_transaction_sql
|
|
175
|
-
|
|
182
|
+
"IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
|
|
176
183
|
end
|
|
177
184
|
|
|
178
185
|
# SQL to COMMIT a transaction.
|
|
179
186
|
def commit_transaction_sql
|
|
180
|
-
|
|
187
|
+
"COMMIT TRANSACTION"
|
|
181
188
|
end
|
|
182
189
|
|
|
183
190
|
# Sybase has both datetime and timestamp classes, most people are going
|
|
@@ -267,26 +274,47 @@ module Sequel
|
|
|
267
274
|
|
|
268
275
|
module DatasetMethods
|
|
269
276
|
BOOL_TRUE = '1'.freeze
|
|
277
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
270
278
|
BOOL_FALSE = '0'.freeze
|
|
279
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
271
280
|
WILDCARD = LiteralString.new('%').freeze
|
|
281
|
+
Sequel::Deprecation.deprecate_constant(self, :WILDCARD)
|
|
272
282
|
TOP = " TOP ".freeze
|
|
283
|
+
Sequel::Deprecation.deprecate_constant(self, :TOP)
|
|
273
284
|
START_AT = " START AT ".freeze
|
|
285
|
+
Sequel::Deprecation.deprecate_constant(self, :START_AT)
|
|
274
286
|
SQL_WITH_RECURSIVE = "WITH RECURSIVE ".freeze
|
|
287
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_WITH_RECURSIVE)
|
|
275
288
|
DATE_FUNCTION = 'today()'.freeze
|
|
289
|
+
Sequel::Deprecation.deprecate_constant(self, :DATE_FUNCTION)
|
|
276
290
|
NOW_FUNCTION = 'now()'.freeze
|
|
291
|
+
Sequel::Deprecation.deprecate_constant(self, :NOW_FUNCTION)
|
|
277
292
|
DATEPART = 'datepart'.freeze
|
|
293
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART)
|
|
278
294
|
REGEXP = 'REGEXP'.freeze
|
|
295
|
+
Sequel::Deprecation.deprecate_constant(self, :REGEXP)
|
|
279
296
|
NOT_REGEXP = 'NOT REGEXP'.freeze
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
297
|
+
Sequel::Deprecation.deprecate_constant(self, :NOT_REGEXP)
|
|
298
|
+
APOS = "'".freeze
|
|
299
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
300
|
+
APOS_RE = /'/.freeze
|
|
301
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS_RE)
|
|
302
|
+
DOUBLE_APOS = "''".freeze
|
|
303
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_APOS)
|
|
283
304
|
BACKSLASH_RE = /\\/.freeze
|
|
305
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKSLASH_RE)
|
|
284
306
|
QUAD_BACKSLASH = "\\\\\\\\".freeze
|
|
307
|
+
Sequel::Deprecation.deprecate_constant(self, :QUAD_BACKSLASH)
|
|
285
308
|
BLOB_START = "0x".freeze
|
|
309
|
+
Sequel::Deprecation.deprecate_constant(self, :BLOB_START)
|
|
286
310
|
HSTAR = "H*".freeze
|
|
311
|
+
Sequel::Deprecation.deprecate_constant(self, :HSTAR)
|
|
287
312
|
CROSS_APPLY = 'CROSS APPLY'.freeze
|
|
313
|
+
Sequel::Deprecation.deprecate_constant(self, :CROSS_APPLY)
|
|
288
314
|
OUTER_APPLY = 'OUTER APPLY'.freeze
|
|
315
|
+
Sequel::Deprecation.deprecate_constant(self, :OUTER_APPLY)
|
|
289
316
|
ONLY_OFFSET = " TOP 2147483647".freeze
|
|
317
|
+
Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
|
|
290
318
|
|
|
291
319
|
Dataset.def_sql_method(self, :insert, %w'with insert into columns values')
|
|
292
320
|
Dataset.def_sql_method(self, :select, %w'with select distinct limit columns into from join where group having compounds order lock')
|
|
@@ -347,12 +375,12 @@ module Sequel
|
|
|
347
375
|
when :<<, :>>
|
|
348
376
|
complex_expression_emulate_append(sql, op, args)
|
|
349
377
|
when :LIKE, :"NOT LIKE"
|
|
350
|
-
sql <<
|
|
351
|
-
literal_append(sql, args
|
|
352
|
-
sql <<
|
|
378
|
+
sql << '('
|
|
379
|
+
literal_append(sql, args[0])
|
|
380
|
+
sql << (op == :LIKE ? ' REGEXP ' : ' NOT REGEXP ')
|
|
353
381
|
pattern = String.new
|
|
354
382
|
last_c = ''
|
|
355
|
-
args
|
|
383
|
+
args[1].each_char do |c|
|
|
356
384
|
if c == '_' and not pattern.end_with?('\\') and last_c != '\\'
|
|
357
385
|
pattern << '.'
|
|
358
386
|
elsif c == '%' and not pattern.end_with?('\\') and last_c != '\\'
|
|
@@ -375,17 +403,17 @@ module Sequel
|
|
|
375
403
|
end
|
|
376
404
|
end
|
|
377
405
|
literal_append(sql, pattern)
|
|
378
|
-
sql <<
|
|
379
|
-
literal_append(sql,
|
|
380
|
-
sql <<
|
|
406
|
+
sql << " ESCAPE "
|
|
407
|
+
literal_append(sql, "\\")
|
|
408
|
+
sql << ')'
|
|
381
409
|
when :ILIKE, :"NOT ILIKE"
|
|
382
410
|
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args)
|
|
383
411
|
when :extract
|
|
384
|
-
sql <<
|
|
385
|
-
literal_append(sql, args
|
|
412
|
+
sql << 'datepart('
|
|
413
|
+
literal_append(sql, args[0])
|
|
386
414
|
sql << ','
|
|
387
|
-
literal_append(sql, args
|
|
388
|
-
sql <<
|
|
415
|
+
literal_append(sql, args[1])
|
|
416
|
+
sql << ')'
|
|
389
417
|
else
|
|
390
418
|
super
|
|
391
419
|
end
|
|
@@ -400,9 +428,9 @@ module Sequel
|
|
|
400
428
|
def constant_sql_append(sql, constant)
|
|
401
429
|
case constant
|
|
402
430
|
when :CURRENT_DATE
|
|
403
|
-
sql <<
|
|
431
|
+
sql << 'today()'
|
|
404
432
|
when :CURRENT_TIMESTAMP, :CURRENT_TIME
|
|
405
|
-
sql <<
|
|
433
|
+
sql << 'now()'
|
|
406
434
|
else
|
|
407
435
|
super
|
|
408
436
|
end
|
|
@@ -417,17 +445,17 @@ module Sequel
|
|
|
417
445
|
|
|
418
446
|
# Use 1 for true on Sybase
|
|
419
447
|
def literal_true
|
|
420
|
-
|
|
448
|
+
'1'
|
|
421
449
|
end
|
|
422
450
|
|
|
423
451
|
# Use 0 for false on Sybase
|
|
424
452
|
def literal_false
|
|
425
|
-
|
|
453
|
+
'0'
|
|
426
454
|
end
|
|
427
455
|
|
|
428
456
|
# SQL fragment for String. Doubles \ and ' by default.
|
|
429
457
|
def literal_string_append(sql, v)
|
|
430
|
-
sql <<
|
|
458
|
+
sql << "'" << v.gsub("\\", "\\\\\\\\").gsub("'", "''") << "'"
|
|
431
459
|
end
|
|
432
460
|
|
|
433
461
|
# SqlAnywhere uses a preceding X for hex escaping strings
|
|
@@ -435,7 +463,7 @@ module Sequel
|
|
|
435
463
|
if v.empty?
|
|
436
464
|
literal_append(sql, "")
|
|
437
465
|
else
|
|
438
|
-
sql <<
|
|
466
|
+
sql << "0x" << v.unpack("H*").first
|
|
439
467
|
end
|
|
440
468
|
end
|
|
441
469
|
|
|
@@ -446,7 +474,7 @@ module Sequel
|
|
|
446
474
|
|
|
447
475
|
def select_into_sql(sql)
|
|
448
476
|
if i = @opts[:into]
|
|
449
|
-
sql <<
|
|
477
|
+
sql << " INTO "
|
|
450
478
|
identifier_append(sql, i)
|
|
451
479
|
end
|
|
452
480
|
end
|
|
@@ -458,14 +486,14 @@ module Sequel
|
|
|
458
486
|
o = @opts[:offset]
|
|
459
487
|
if l || o
|
|
460
488
|
if l
|
|
461
|
-
sql << TOP
|
|
489
|
+
sql << " TOP "
|
|
462
490
|
literal_append(sql, l)
|
|
463
491
|
else
|
|
464
|
-
sql <<
|
|
492
|
+
sql << " TOP 2147483647"
|
|
465
493
|
end
|
|
466
494
|
|
|
467
495
|
if o
|
|
468
|
-
sql <<
|
|
496
|
+
sql << " START AT ("
|
|
469
497
|
literal_append(sql, o)
|
|
470
498
|
sql << " + 1)"
|
|
471
499
|
end
|
|
@@ -474,15 +502,15 @@ module Sequel
|
|
|
474
502
|
|
|
475
503
|
# Use WITH RECURSIVE instead of WITH if any of the CTEs is recursive
|
|
476
504
|
def select_with_sql_base
|
|
477
|
-
opts[:with].any?{|w| w[:recursive]} ?
|
|
505
|
+
opts[:with].any?{|w| w[:recursive]} ? "WITH RECURSIVE " : super
|
|
478
506
|
end
|
|
479
507
|
|
|
480
508
|
def join_type_sql(join_type)
|
|
481
509
|
case join_type
|
|
482
510
|
when :cross_apply
|
|
483
|
-
|
|
511
|
+
'CROSS APPLY'
|
|
484
512
|
when :outer_apply
|
|
485
|
-
|
|
513
|
+
'OUTER APPLY'
|
|
486
514
|
else
|
|
487
515
|
super
|
|
488
516
|
end
|