sequel 4.39.0 → 4.40.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 +34 -0
- data/README.rdoc +8 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +7 -7
- data/doc/association_basics.rdoc +7 -7
- data/doc/cheat_sheet.rdoc +5 -3
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/object_model.rdoc +16 -7
- data/doc/postgresql.rdoc +3 -3
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.40.0.txt +179 -0
- data/doc/security.rdoc +2 -1
- data/doc/sql.rdoc +34 -18
- data/doc/testing.rdoc +1 -0
- data/doc/virtual_rows.rdoc +11 -2
- data/lib/sequel/adapters/jdbc/derby.rb +7 -1
- data/lib/sequel/adapters/jdbc/h2.rb +15 -1
- data/lib/sequel/adapters/oracle.rb +9 -5
- data/lib/sequel/adapters/postgres.rb +0 -1
- data/lib/sequel/adapters/shared/cubrid.rb +11 -11
- data/lib/sequel/adapters/shared/db2.rb +4 -8
- data/lib/sequel/adapters/shared/mssql.rb +41 -28
- data/lib/sequel/adapters/shared/mysql.rb +9 -6
- data/lib/sequel/adapters/shared/oracle.rb +16 -5
- data/lib/sequel/adapters/shared/postgres.rb +84 -45
- data/lib/sequel/adapters/shared/sqlanywhere.rb +29 -15
- data/lib/sequel/adapters/shared/sqlite.rb +6 -6
- data/lib/sequel/core.rb +61 -10
- data/lib/sequel/database/connecting.rb +2 -1
- data/lib/sequel/database/features.rb +7 -0
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +30 -3
- data/lib/sequel/database/transactions.rb +4 -2
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/graph.rb +6 -1
- data/lib/sequel/dataset/query.rb +14 -7
- data/lib/sequel/dataset/sql.rb +2 -2
- data/lib/sequel/extensions/core_extensions.rb +2 -1
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/s.rb +57 -0
- data/lib/sequel/extensions/set_overrides.rb +5 -1
- data/lib/sequel/extensions/sql_expr.rb +1 -0
- data/lib/sequel/extensions/symbol_aref.rb +71 -0
- data/lib/sequel/extensions/symbol_aref_refinement.rb +41 -0
- data/lib/sequel/extensions/symbol_as.rb +23 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +35 -0
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/plugins/class_table_inheritance.rb +14 -3
- data/lib/sequel/plugins/column_select.rb +4 -2
- data/lib/sequel/plugins/dataset_associations.rb +12 -4
- data/lib/sequel/plugins/insert_returning_select.rb +1 -1
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/prepared_statements.rb +1 -0
- data/lib/sequel/sql.rb +40 -8
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +3 -3
- data/spec/adapters/mssql_spec.rb +40 -40
- data/spec/adapters/mysql_spec.rb +5 -5
- data/spec/adapters/oracle_spec.rb +4 -4
- data/spec/adapters/postgres_spec.rb +135 -124
- data/spec/adapters/spec_helper.rb +1 -0
- data/spec/adapters/sqlite_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +2 -2
- data/spec/core/expression_filters_spec.rb +43 -2
- data/spec/core/schema_spec.rb +35 -1
- data/spec/core_extensions_spec.rb +27 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -0
- data/spec/extensions/column_select_spec.rb +8 -0
- data/spec/extensions/core_refinements_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +9 -0
- data/spec/extensions/insert_returning_select_spec.rb +20 -0
- data/spec/extensions/prepared_statements_spec.rb +7 -0
- data/spec/extensions/s_spec.rb +60 -0
- data/spec/extensions/symbol_aref_refinement_spec.rb +28 -0
- data/spec/extensions/symbol_as_refinement_spec.rb +21 -0
- data/spec/integration/associations_test.rb +62 -57
- data/spec/integration/dataset_test.rb +54 -54
- data/spec/integration/eager_loader_test.rb +7 -7
- data/spec/integration/plugin_test.rb +20 -20
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +21 -0
- data/spec/integration/spec_helper.rb +1 -0
- metadata +12 -2
data/doc/security.rdoc
CHANGED
@@ -242,7 +242,8 @@ derived from user input unless absolutely necessary.
|
|
242
242
|
|
243
243
|
Sequel also allows you to create identifiers using
|
244
244
|
Sequel.identifier[rdoc-ref:Sequel::SQL::Builders#identifier] for plain identifiers,
|
245
|
-
Sequel.qualify[rdoc-ref:Sequel::SQL::Builders#qualify]
|
245
|
+
Sequel.qualify[rdoc-ref:Sequel::SQL::Builders#qualify] and
|
246
|
+
Sequel::SQL::Indentifier#[][rdoc-ref:Sequel::SQL::QualifyingMethods#[]] for qualified identifiers, and
|
246
247
|
Sequel.as[rdoc-ref:Sequel::SQL::Builders#as] for aliased expressions. So if you
|
247
248
|
pass any of those values derived from user input, you are dealing with the same scenario.
|
248
249
|
|
data/doc/sql.rdoc
CHANGED
@@ -125,6 +125,8 @@ A plain symbol is usually treated as an unqualified identifier. However, if you
|
|
125
125
|
|
126
126
|
:table__column # "table"."column"
|
127
127
|
|
128
|
+
This works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
|
129
|
+
|
128
130
|
Note that you can't use a period to separate them:
|
129
131
|
|
130
132
|
:table.column # calls the column method on the symbol
|
@@ -133,14 +135,21 @@ Also note that specifying the period inside the symbol doesn't work if you are q
|
|
133
135
|
|
134
136
|
:"table.column" # "table.column"
|
135
137
|
|
136
|
-
|
138
|
+
A couple other ways two create a qualified identifier are to use <tt>Sequel.[]</tt> to create an identifier,
|
139
|
+
and call <tt>[]</tt> or +qualify+ on that, or to use the <tt>Sequel.qualify</tt> with the table and column symbols:
|
137
140
|
|
141
|
+
Sequel[:table][:column] # "table"."column"
|
142
|
+
Sequel[:column].qualify(:table) # "table"."column"
|
138
143
|
Sequel.qualify(:table, :column) # "table"."column"
|
139
144
|
|
140
145
|
Another way to generate identifiers is to use Sequel's {virtual row support}[rdoc-ref:doc/virtual_rows.rdoc]:
|
141
146
|
|
142
147
|
DB[:albums].select{name} # SELECT "name" FROM "albums"
|
143
|
-
DB[:albums].select{
|
148
|
+
DB[:albums].select{albums[:name]} # SELECT "albums"."name" FROM "albums"
|
149
|
+
|
150
|
+
You can also use the symbol_aref extension for creating qualified identifiers:
|
151
|
+
|
152
|
+
:table[:column] # "table"."column"
|
144
153
|
|
145
154
|
=== Numbers
|
146
155
|
|
@@ -173,10 +182,17 @@ You can combine this with implicit qualification:
|
|
173
182
|
|
174
183
|
:table__column___alias # "table"."column" AS "alias"
|
175
184
|
|
185
|
+
As with creating qualified identifiers via a double underscore, This works by default, but it is possible to turn off by setting <tt>Sequel.split_symbols = false</tt>.
|
186
|
+
|
176
187
|
You can also use the <tt>Sequel.as</tt> method to create an alias, and the +as+ method on most Sequel-specific expression objects:
|
177
188
|
|
178
|
-
Sequel.as(:column, :alias)
|
179
|
-
Sequel
|
189
|
+
Sequel.as(:column, :alias) # "column" AS "alias"
|
190
|
+
Sequel[:column].as(:alias) # "column" AS "alias"
|
191
|
+
Sequel[:table][:column].as(:alias) # "table"."column" AS "alias"
|
192
|
+
|
193
|
+
You can also use the symbol_as extension for creating aliased identifiers:
|
194
|
+
|
195
|
+
:column.as(:alias) # "column" AS "alias"
|
180
196
|
|
181
197
|
If you want to use a derived column list, you can provide an array of column aliases:
|
182
198
|
|
@@ -231,10 +247,10 @@ If the database supports window functions, Sequel can handle them by calling the
|
|
231
247
|
|
232
248
|
If the database supports schema qualified functions, Sequel can handle them by calling the function method on a QuailfiedIdentifier:
|
233
249
|
|
234
|
-
DB[:albums].select{
|
250
|
+
DB[:albums].select{schema[:function].function}
|
235
251
|
# SELECT schema.function() FROM albums
|
236
252
|
|
237
|
-
DB[:albums].select{
|
253
|
+
DB[:albums].select{schema[:function].function(col, 2, "a")}
|
238
254
|
# SELECT schema.function(col, 2, 'a') FROM albums
|
239
255
|
|
240
256
|
=== Portable/Emulated Functions
|
@@ -347,8 +363,8 @@ produces <tt>(column != 1)</tt> instead of <tt>NOT (column = 1)</tt>.
|
|
347
363
|
|
348
364
|
Sequel defines the inequality operators directly on most Sequel-specific expression objects:
|
349
365
|
|
350
|
-
Sequel
|
351
|
-
Sequel
|
366
|
+
Sequel[:table][:column] > 1 # ("table"."column" > 1)
|
367
|
+
Sequel[:table][:column] < 1 # ("table"."column" < 1)
|
352
368
|
Sequel.function(:func) >= 1 # (func() >= 1)
|
353
369
|
Sequel.function(:func, :column) <= 1 # (func("column") <= 1)
|
354
370
|
|
@@ -365,23 +381,23 @@ A common use of virtual rows is to handle inequality operators:
|
|
365
381
|
The standard mathematical operates are defined on most Sequel-specific expression objects:
|
366
382
|
|
367
383
|
Sequel[:column] + 1 # "column" + 1
|
368
|
-
Sequel[:
|
369
|
-
Sequel
|
384
|
+
Sequel[:table][:column] - 1 # "table"."column" - 1
|
385
|
+
Sequel[:table][:column] * 1 # "table"."column" * 1
|
370
386
|
Sequel[:column] / 1 # "column" / 1
|
371
387
|
Sequel[:column] ** 1 # power("column", 1)
|
372
388
|
|
373
389
|
You can also call the operator methods directly on the Sequel module:
|
374
390
|
|
375
391
|
Sequel.+(:column, 1) # "column" + 1
|
376
|
-
Sequel.-(:
|
377
|
-
Sequel.*(Sequel
|
392
|
+
Sequel.-(Sequel[:table][:column], 1) # "table"."column" - 1
|
393
|
+
Sequel.*(Sequel[:table][:column], 1) # "table"."column" * 1
|
378
394
|
Sequel./(:column, 1) # "column" / 1
|
379
395
|
Sequel.**(:column, 1) # power("column", 1)
|
380
396
|
|
381
397
|
Note that since Sequel implements support for ruby's coercion protocol, the following also works:
|
382
398
|
|
383
399
|
1 + Sequel[:column]
|
384
|
-
1 - Sequel
|
400
|
+
1 - Sequel[:table][:column]
|
385
401
|
|
386
402
|
=== Boolean Operators (AND OR)
|
387
403
|
|
@@ -432,7 +448,7 @@ Casting in Sequel is done with the +cast+ method, which is available on most of
|
|
432
448
|
|
433
449
|
Sequel[:name].cast(:text) # CAST("name" AS text)
|
434
450
|
Sequel['1'].cast(:integer) # CAST('1' AS integer)
|
435
|
-
Sequel
|
451
|
+
Sequel[:table][:column].cast(:date) # CAST("table"."column" AS date)
|
436
452
|
|
437
453
|
You can also use the <tt>Sequel.cast</tt> method:
|
438
454
|
|
@@ -516,17 +532,17 @@ Note that using +ilike+ with a regular expression will always make the regexp ca
|
|
516
532
|
Sequel supports specifying ascending or descending order using the +asc+ and +desc+ method on most Sequel-specific expression objects:
|
517
533
|
|
518
534
|
Sequel[:column].asc # "column" ASC
|
519
|
-
Sequel[:column].
|
535
|
+
Sequel[:table][:column].desc # "table"."column" DESC
|
520
536
|
|
521
537
|
You can also use the <tt>Sequel.asc</tt> and <tt>Sequel.desc</tt> methods:
|
522
538
|
|
523
539
|
Sequel.asc(:column) # "column" ASC
|
524
|
-
Sequel.desc(Sequel[:column]
|
540
|
+
Sequel.desc(Sequel[:table][:column]) # "table"."column" DESC
|
525
541
|
|
526
542
|
On some databases, you can specify null ordering:
|
527
543
|
|
528
544
|
Sequel.asc(:column, :nulls=>:first) # "column" ASC NULLS FIRST
|
529
|
-
Sequel.desc(Sequel[:column]
|
545
|
+
Sequel.desc(Sequel[:table][:column], :nulls=>:last) # "table"."column" DESC NULLS LAST
|
530
546
|
|
531
547
|
=== All Columns (.*)
|
532
548
|
|
@@ -556,7 +572,7 @@ If you provide a 3rd argument to <tt>Sequel.case</tt>, it goes between CASE and
|
|
556
572
|
Sequel supports SQL subscripts using the +sql_subscript+ method on most Sequel-specific expression objects:
|
557
573
|
|
558
574
|
Sequel[:column].sql_subscript(3) # column[3]
|
559
|
-
Sequel[:column].
|
575
|
+
Sequel[:table][:column].sql_subscript(3) # table.column[3]
|
560
576
|
|
561
577
|
You can also use the <tt>Sequel.subscript</tt> method:
|
562
578
|
|
data/doc/testing.rdoc
CHANGED
@@ -159,5 +159,6 @@ SEQUEL_ERROR_SQL :: Use the error_sql extension when running the specs
|
|
159
159
|
SEQUEL_NO_AUTO_LITERAL_STRINGS :: Use the no_auto_string_literals extension when running the specs
|
160
160
|
SEQUEL_NO_CACHE_ASSOCIATIONS :: Don't cache association metadata when running the specs
|
161
161
|
SEQUEL_NO_CHECK_SQLS :: Don't check for specific SQL syntax when running the specs
|
162
|
+
SEQUEL_NO_SPLIT_SYMBOLS :: Turn off symbol splitting when running the specs
|
162
163
|
SEQUEL_NO_PENDING :: Don't skip any specs, try running all specs (note, can cause lockups for some adapters)
|
163
164
|
SKIPPED_TEST_WARN :: Warn when skipping any tests because libraries aren't available
|
data/doc/virtual_rows.rdoc
CHANGED
@@ -121,8 +121,17 @@ in the method name:
|
|
121
121
|
# WHERE table.column > 1
|
122
122
|
|
123
123
|
Using the double underscore for SQL::QualifiedIdentifiers was done to make
|
124
|
-
usage very similar to using symbols, which also translate the
|
125
|
-
into a qualified column.
|
124
|
+
usage very similar to using symbols, which by default also translate the
|
125
|
+
double underscore into a qualified column.
|
126
|
+
|
127
|
+
Note that when <tt>Sequel.split_symbols = false</tt> is used, then virtual
|
128
|
+
rows do not split symbols either. If you need to create qualified identifers
|
129
|
+
when disabling symbol splitting, it is easy to do by calling #[] on the
|
130
|
+
SQL::Identifiers returned by regular methods calls:
|
131
|
+
|
132
|
+
ds.where{|o| o.table[:column] > 1}
|
133
|
+
ds.where{table[:column] > 1}
|
134
|
+
# WHERE table.column > 1
|
126
135
|
|
127
136
|
== SQL::Functions - SQL function calls
|
128
137
|
|
@@ -82,9 +82,15 @@ module Sequel
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
# Derby does not allow adding primary key constraints to NULLable columns.
|
86
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
85
90
|
# Derby doesn't allow specifying NULL for columns, only NOT NULL.
|
86
91
|
def column_definition_null_sql(sql, column)
|
87
|
-
|
92
|
+
null = column.fetch(:null, column[:allow_null])
|
93
|
+
sql << " NOT NULL" if null == false || (null.nil? && column[:primary_key])
|
88
94
|
end
|
89
95
|
|
90
96
|
# Add NOT LOGGED for temporary tables to improve performance.
|
@@ -58,6 +58,11 @@ module Sequel
|
|
58
58
|
|
59
59
|
private
|
60
60
|
|
61
|
+
# H2 does not allow adding primary key constraints to NULLable columns.
|
62
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
61
66
|
# If the :prepare option is given and we aren't in a savepoint,
|
62
67
|
# prepare the transaction for a two-phase commit.
|
63
68
|
def commit_transaction(conn, opts=OPTS)
|
@@ -73,12 +78,21 @@ module Sequel
|
|
73
78
|
case op[:op]
|
74
79
|
when :add_column
|
75
80
|
if (pk = op.delete(:primary_key)) || (ref = op.delete(:table))
|
81
|
+
if pk
|
82
|
+
op[:null] = false
|
83
|
+
end
|
84
|
+
|
76
85
|
sqls = [super(table, op)]
|
77
|
-
|
86
|
+
|
87
|
+
if pk && op[:type] != :identity
|
88
|
+
sqls << "ALTER TABLE #{quote_schema_table(table)} ADD PRIMARY KEY (#{quote_identifier(op[:name])})"
|
89
|
+
end
|
90
|
+
|
78
91
|
if ref
|
79
92
|
op[:table] = ref
|
80
93
|
sqls << "ALTER TABLE #{quote_schema_table(table)} ADD FOREIGN KEY (#{quote_identifier(op[:name])}) #{column_references_sql(op)}"
|
81
94
|
end
|
95
|
+
|
82
96
|
sqls
|
83
97
|
else
|
84
98
|
super(table, op)
|
@@ -264,11 +264,15 @@ module Sequel
|
|
264
264
|
im = input_identifier_meth(ds)
|
265
265
|
|
266
266
|
# Primary Keys
|
267
|
-
ds = metadata_dataset.
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
267
|
+
ds = metadata_dataset.
|
268
|
+
from{[all_constraints.as(:cons), all_cons_columns.as(:cols)]}.
|
269
|
+
where{{
|
270
|
+
cols[:table_name]=>im.call(table),
|
271
|
+
cons[:constraint_type]=>'P',
|
272
|
+
cons[:constraint_name]=>cols[:constraint_name],
|
273
|
+
cons[:owner]=>cols[:owner]}}
|
274
|
+
ds = ds.where{{cons[:owner]=>im.call(schema)}} if schema
|
275
|
+
pks = ds.select_map{cols[:column_name]}
|
272
276
|
|
273
277
|
# Default values
|
274
278
|
defaults = begin
|
@@ -23,11 +23,11 @@ module Sequel
|
|
23
23
|
m2 = input_identifier_meth
|
24
24
|
indexes = {}
|
25
25
|
metadata_dataset.
|
26
|
-
from
|
27
|
-
join(:
|
28
|
-
where
|
29
|
-
order
|
30
|
-
select
|
26
|
+
from{db_index[:i]}.
|
27
|
+
join(Sequel[:db_index_key].as(:k), :index_name=>:index_name, :class_name=>:class_name).
|
28
|
+
where{{i[:class_name]=>m2.call(table), :is_primary_key=>'NO'}}.
|
29
|
+
order{k[:key_order]}.
|
30
|
+
select{[i[:index_name], k[:key_attr_name].as(:column), :is_unique]}.
|
31
31
|
each do |row|
|
32
32
|
index = indexes[m.call(row[:index_name])] ||= {:columns=>[], :unique=>row[:is_unique]=='YES'}
|
33
33
|
index[:columns] << m.call(row[:column])
|
@@ -44,18 +44,18 @@ module Sequel
|
|
44
44
|
m2 = input_identifier_meth(opts[:dataset])
|
45
45
|
|
46
46
|
pks = metadata_dataset.
|
47
|
-
from
|
48
|
-
join(:
|
49
|
-
where
|
50
|
-
order
|
51
|
-
select_map
|
47
|
+
from{db_index[:i]}.
|
48
|
+
join(Sequel[:db_index_key].as(:k), :index_name=>:index_name, :class_name=>:class_name).
|
49
|
+
where{{i[:class_name]=>m2.call(table_name), :is_primary_key=>'YES'}}.
|
50
|
+
order{k[:key_order]}.
|
51
|
+
select_map{k[:key_attr_name]}.
|
52
52
|
map{|c| m.call(c)}
|
53
53
|
|
54
54
|
metadata_dataset.
|
55
55
|
from(:db_attribute).
|
56
56
|
where(:class_name=>m2.call(table_name)).
|
57
57
|
order(:def_order).
|
58
|
-
select
|
58
|
+
select{[:attr_name, data_type.as(:db_type), default_value.as(:default), is_nullable.as(:allow_null), :prec]}.
|
59
59
|
map do |row|
|
60
60
|
name = m.call(row.delete(:attr_name))
|
61
61
|
row[:allow_null] = row[:allow_null] == 'YES'
|
@@ -76,7 +76,7 @@ module Sequel
|
|
76
76
|
m = output_identifier_meth
|
77
77
|
indexes = {}
|
78
78
|
metadata_dataset.
|
79
|
-
from(:
|
79
|
+
from(Sequel[:syscat][:indexes]).
|
80
80
|
select(:indname, :uniquerule, :colnames).
|
81
81
|
where(:tabname=>input_identifier_meth.call(table), :system_required=>0).
|
82
82
|
each do |r|
|
@@ -160,13 +160,9 @@ module Sequel
|
|
160
160
|
AUTOINCREMENT
|
161
161
|
end
|
162
162
|
|
163
|
-
#
|
164
|
-
def
|
165
|
-
|
166
|
-
null = false if column[:primary_key]
|
167
|
-
|
168
|
-
sql << NOT_NULL if null == false
|
169
|
-
sql << NULL if null == true
|
163
|
+
# DB2 does not allow adding primary key constraints to NULLable columns.
|
164
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
165
|
+
false
|
170
166
|
end
|
171
167
|
|
172
168
|
# Supply columns with NOT NULL if they are part of a composite
|
@@ -3,7 +3,6 @@
|
|
3
3
|
Sequel.require %w'emulate_offset_with_row_number split_alter_table', 'adapters/utils'
|
4
4
|
|
5
5
|
module Sequel
|
6
|
-
Dataset::NON_SQL_OPTIONS << :disable_insert_output
|
7
6
|
module MSSQL
|
8
7
|
Sequel::Database.set_shared_adapter_scheme(:mssql, self)
|
9
8
|
|
@@ -141,20 +140,22 @@ module Sequel
|
|
141
140
|
schema, table = schema_and_table(table)
|
142
141
|
current_schema = m.call(get(Sequel.function('schema_name')))
|
143
142
|
fk_action_map = FOREIGN_KEY_ACTION_MAP
|
143
|
+
fk = Sequel[:fk]
|
144
|
+
fkc = Sequel[:fkc]
|
144
145
|
ds = metadata_dataset.from(Sequel.lit('[sys].[foreign_keys]').as(:fk)).
|
145
146
|
join(Sequel.lit('[sys].[foreign_key_columns]').as(:fkc), :constraint_object_id => :object_id).
|
146
|
-
join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => :
|
147
|
-
join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => :
|
148
|
-
where{{object_schema_name(:
|
149
|
-
where{{object_name(:
|
150
|
-
select{[:
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
155
|
-
object_schema_name(:
|
156
|
-
object_name(:
|
157
|
-
order(:
|
147
|
+
join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => fkc[:parent_object_id], :column_id => fkc[:parent_column_id]).
|
148
|
+
join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => fkc[:referenced_object_id], :column_id => fkc[:referenced_column_id]).
|
149
|
+
where{{object_schema_name(fk[:parent_object_id]) => im.call(schema || current_schema)}}.
|
150
|
+
where{{object_name(fk[:parent_object_id]) => im.call(table)}}.
|
151
|
+
select{[fk[:name],
|
152
|
+
fk[:delete_referential_action],
|
153
|
+
fk[:update_referential_action],
|
154
|
+
pc[:name].as(:column),
|
155
|
+
rc[:name].as(:referenced_column),
|
156
|
+
object_schema_name(fk[:referenced_object_id]).as(:schema),
|
157
|
+
object_name(fk[:referenced_object_id]).as(:table)]}.
|
158
|
+
order(fk[:name], fkc[:constraint_column_id])
|
158
159
|
h = {}
|
159
160
|
ds.each do |row|
|
160
161
|
if r = h[row[:name]]
|
@@ -179,17 +180,18 @@ module Sequel
|
|
179
180
|
m = output_identifier_meth
|
180
181
|
im = input_identifier_meth
|
181
182
|
indexes = {}
|
183
|
+
i = Sequel[:i]
|
182
184
|
ds = metadata_dataset.from(Sequel.lit('[sys].[tables]').as(:t)).
|
183
185
|
join(Sequel.lit('[sys].[indexes]').as(:i), :object_id=>:object_id).
|
184
186
|
join(Sequel.lit('[sys].[index_columns]').as(:ic), :object_id=>:object_id, :index_id=>:index_id).
|
185
187
|
join(Sequel.lit('[sys].[columns]').as(:c), :object_id=>:object_id, :column_id=>:column_id).
|
186
|
-
select(:
|
187
|
-
where{{
|
188
|
-
where(:
|
189
|
-
order(:
|
188
|
+
select(i[:name], i[:is_unique], Sequel[:c][:name].as(:column)).
|
189
|
+
where{{t[:name]=>im.call(table)}}.
|
190
|
+
where(i[:is_primary_key]=>0, i[:is_disabled]=>0).
|
191
|
+
order(i[:name], Sequel[:ic][:index_column_id])
|
190
192
|
|
191
193
|
if supports_partial_indexes?
|
192
|
-
ds = ds.where(:
|
194
|
+
ds = ds.where(i[:has_filter]=>0)
|
193
195
|
end
|
194
196
|
|
195
197
|
ds.each do |r|
|
@@ -313,6 +315,11 @@ module Sequel
|
|
313
315
|
SQL_BEGIN
|
314
316
|
end
|
315
317
|
|
318
|
+
# MSSQL does not allow adding primary key constraints to NULLable columns.
|
319
|
+
def can_add_primary_key_constraint_on_nullable_columns?
|
320
|
+
false
|
321
|
+
end
|
322
|
+
|
316
323
|
# Handle MSSQL specific default format.
|
317
324
|
def column_schema_normalize_default(default, type)
|
318
325
|
if m = MSSQL_DEFAULT_RE.match(default)
|
@@ -365,7 +372,7 @@ module Sequel
|
|
365
372
|
def default_constraint_name(table, column_name)
|
366
373
|
if server_version >= 9000000
|
367
374
|
table_name = schema_and_table(table).compact.join('.')
|
368
|
-
self[:
|
375
|
+
self[Sequel[:sys][:default_constraints]].
|
369
376
|
where{{:parent_object_id => Sequel::SQL::Function.new(:object_id, table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
|
370
377
|
get(:name)
|
371
378
|
end
|
@@ -390,7 +397,7 @@ module Sequel
|
|
390
397
|
# Backbone of the tables and views support.
|
391
398
|
def information_schema_tables(type, opts)
|
392
399
|
m = output_identifier_meth
|
393
|
-
metadata_dataset.from(:
|
400
|
+
metadata_dataset.from(Sequel[:information_schema][:tables].as(:t)).
|
394
401
|
select(:table_name).
|
395
402
|
filter(:table_type=>type, :table_schema=>(opts[:schema]||'dbo').to_s).
|
396
403
|
map{|x| m.call(x[:table_name])}
|
@@ -453,17 +460,17 @@ module Sequel
|
|
453
460
|
get(:indid)
|
454
461
|
pk_cols = metadata_dataset.from(sys_qual.call(Sequel.lit('sysindexkeys')).as(:sik)).
|
455
462
|
join(sys_qual.call(Sequel.lit('syscolumns')).as(:sc), :id=>:id, :colid=>:colid).
|
456
|
-
where
|
457
|
-
select_order_map
|
463
|
+
where{{sik[:id]=>table_id, sik[:indid]=>pk_index_id}}.
|
464
|
+
select_order_map{sc[:name]}
|
458
465
|
|
459
|
-
ds = metadata_dataset.from(inf_sch_qual.call(:
|
460
|
-
join(inf_sch_qual.call(:
|
466
|
+
ds = metadata_dataset.from(inf_sch_qual.call(Sequel[:information_schema][:tables]).as(:t)).
|
467
|
+
join(inf_sch_qual.call(Sequel[:information_schema][:columns]).as(:c), :table_catalog=>:table_catalog,
|
461
468
|
:table_schema => :table_schema, :table_name => :table_name).
|
462
|
-
select(:
|
463
|
-
|
469
|
+
select{[column_name.as(:column), data_type.as(:db_type), character_maximum_length.as(:max_chars), column_default.as(:default), is_nullable.as(:allow_null), numeric_precision.as(:column_size), numeric_scale.as(:scale)]}.
|
470
|
+
where{{c[:table_name]=>tn}}
|
464
471
|
|
465
472
|
if schema = opts[:schema]
|
466
|
-
ds.
|
473
|
+
ds = ds.where{{c[:table_schema]=>schema}}
|
467
474
|
end
|
468
475
|
|
469
476
|
ds.map do |row|
|
@@ -567,12 +574,13 @@ module Sequel
|
|
567
574
|
ROWS_ONLY = " ROWS ONLY".freeze
|
568
575
|
FETCH_NEXT = " FETCH NEXT ".freeze
|
569
576
|
|
577
|
+
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output]).freeze
|
578
|
+
|
570
579
|
Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
|
571
580
|
Dataset.def_sql_method(self, :delete, %w'with delete from output from2 where')
|
572
581
|
Dataset.def_sql_method(self, :insert, %w'with insert into columns output values')
|
573
582
|
Dataset.def_sql_method(self, :update, [['if is_2005_or_later?', %w'with update limit table set output from where'], ['else', %w'update table set output from where']])
|
574
583
|
|
575
|
-
|
576
584
|
# Allow overriding of the mssql_unicode_strings option at the dataset level.
|
577
585
|
attr_writer :mssql_unicode_strings
|
578
586
|
|
@@ -953,6 +961,11 @@ module Sequel
|
|
953
961
|
is_2008_or_later? ? :values : :union
|
954
962
|
end
|
955
963
|
|
964
|
+
# Dataset options that do not affect the generated SQL.
|
965
|
+
def non_sql_options
|
966
|
+
NON_SQL_OPTIONS
|
967
|
+
end
|
968
|
+
|
956
969
|
def select_into_sql(sql)
|
957
970
|
if i = @opts[:into]
|
958
971
|
sql << INTO
|