50
48
when Dataset, Array, LiteralString
53
if vals.respond_to?(:values) && (v = vals.values).is_a?(Hash)
58
52
if (v0 = values.at(0)).is_a?(Array) && ((v1 = values.at(1)).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
155
149
check_truncation_allowed!
156
150
raise(InvalidOperation, "Can't truncate filtered datasets") if opts[:where] || opts[:having]
157
_truncate_sql(source_list(opts[:from]))
152
source_list_append(t, opts[:from])
166
162
# Raises an +Error+ if the dataset is grouped or includes more
167
163
# than one table.
168
def update_sql(values = {})
164
def update_sql(values = OPTS)
169
165
return static_sql(opts[:sql]) if opts[:sql]
170
166
check_modification_allowed!
171
167
clone(:values=>values)._update_sql
182
178
clauses.map{|clause| :"#{type}_#{clause}_sql"}.freeze
181
# Map of emulated function names to native function names.
182
EMULATED_FUNCTION_MAP = {}
185
184
WILDCARD = LiteralString.new('*').freeze
186
185
ALL = ' ALL'.freeze
187
186
AND_SEPARATOR = " AND ".freeze
200
200
CASE_THEN = " THEN ".freeze
201
201
CASE_WHEN = " WHEN ".freeze
202
202
CAST_OPEN = 'CAST('.freeze
203
COLUMN_REF_RE1 = /\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/.freeze
204
COLUMN_REF_RE2 = /\A((?:(?!___).)+)___(.+)\z/.freeze
205
COLUMN_REF_RE3 = /\A((?:(?!__).)+)__(.+)\z/.freeze
204
COLUMN_REF_RE1 = Sequel::COLUMN_REF_RE1
205
COLUMN_REF_RE2 = Sequel::COLUMN_REF_RE2
206
COLUMN_REF_RE3 = Sequel::COLUMN_REF_RE3
206
207
COMMA = ', '.freeze
207
208
COMMA_SEPARATOR = COMMA
208
209
CONDITION_FALSE = '(1 = 0)'.freeze
209
210
CONDITION_TRUE = '(1 = 1)'.freeze
210
COUNT_FROM_SELF_OPTS = [:distinct, :group, :sql, :limit, :compounds]
211
COUNT_FROM_SELF_OPTS = [:distinct, :group, :sql, :limit, :offset, :compounds]
211
212
COUNT_OF_ALL_AS_COUNT = SQL::Function.new(:count, WILDCARD).as(:count)
212
213
DATASET_ALIAS_BASE_NAME = 't'.freeze
213
214
DEFAULT = LiteralString.new('DEFAULT').freeze
220
221
DOUBLE_APOS = "''".freeze
221
222
DOUBLE_QUOTE = '""'.freeze
222
223
EQUAL = ' = '.freeze
224
ESCAPE = " ESCAPE ".freeze
223
225
EXTRACT = 'extract('.freeze
224
226
EXISTS = ['EXISTS '.freeze].freeze
225
227
FOR_UPDATE = ' FOR UPDATE'.freeze
240
242
INTO = " INTO ".freeze
241
243
IS_LITERALS = {nil=>'NULL'.freeze, true=>'TRUE'.freeze, false=>'FALSE'.freeze}.freeze
242
244
IS_OPERATORS = ::Sequel::SQL::ComplexExpression::IS_OPERATORS
245
LIKE_OPERATORS = ::Sequel::SQL::ComplexExpression::LIKE_OPERATORS
243
246
LIMIT = " LIMIT ".freeze
244
247
N_ARITY_OPERATORS = ::Sequel::SQL::ComplexExpression::N_ARITY_OPERATORS
245
248
NOT_SPACE = 'NOT '.freeze
272
275
TIMESTAMP_FORMAT = "'%Y-%m-%d %H:%M:%S%N%z'".freeze
273
276
STANDARD_TIMESTAMP_FORMAT = "TIMESTAMP #{TIMESTAMP_FORMAT}".freeze
274
277
TWO_ARITY_OPERATORS = ::Sequel::SQL::ComplexExpression::TWO_ARITY_OPERATORS
278
REGEXP_OPERATORS = ::Sequel::SQL::ComplexExpression::REGEXP_OPERATORS
275
279
UNDERSCORE = '_'.freeze
276
280
UPDATE = 'UPDATE'.freeze
277
281
UPDATE_CLAUSE_METHODS = clause_methods(:update, %w'update table set where')
280
284
V190 = '1.9.0'.freeze
281
285
WHERE = " WHERE ".freeze
283
PUBLIC_APPEND_METHODS = (<<-END).split.map{|x| x.to_sym}
285
aliased_expression_sql
291
complex_expression_sql
296
join_using_clause_sql
297
negative_boolean_constant_sql
298
ordered_expression_sql
299
placeholder_literal_string_sql
300
qualified_identifier_sql
308
PRIVATE_APPEND_METHODS = (<<-END).split.map{|x| x.to_sym}
326
def self.def_append_methods(meths)
328
class_eval(<<-END, __FILE__, __LINE__ + 1)
329
def #{meth}(*args, &block)
331
#{meth}_append(s, *args, &block)
287
[:literal, :quote_identifier, :quote_schema_table].each do |meth|
288
class_eval(<<-END, __FILE__, __LINE__ + 1)
289
def #{meth}(*args, &block)
291
#{meth}_append(s, *args, &block)
337
def_append_methods(PUBLIC_APPEND_METHODS + PRIVATE_APPEND_METHODS)
338
private *PRIVATE_APPEND_METHODS
340
297
# SQL fragment for AliasedExpression
341
298
def aliased_expression_sql_append(sql, ae)
402
359
when *IS_OPERATORS
404
361
if r.nil? || supports_is_true?
405
raise(InvalidOperation, 'Invalid argument used for IS operator') unless v = IS_LITERALS[r]
362
raise(InvalidOperation, 'Invalid argument used for IS operator') unless val = IS_LITERALS[r]
406
363
sql << PAREN_OPEN
407
364
literal_append(sql, args.at(0))
408
365
sql << SPACE << op.to_s << SPACE
409
sql << v << PAREN_CLOSE
366
sql << val << PAREN_CLOSE
411
368
complex_expression_sql_append(sql, :"=", args)
455
412
literal_append(sql, vals)
456
413
sql << PAREN_CLOSE
415
when :LIKE, :'NOT LIKE'
417
literal_append(sql, args.at(0))
418
sql << SPACE << op.to_s << SPACE
419
literal_append(sql, args.at(1))
421
literal_append(sql, BACKSLASH)
423
when :ILIKE, :'NOT ILIKE'
424
complex_expression_sql_append(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|v| Sequel.function(:UPPER, v)})
458
425
when *TWO_ARITY_OPERATORS
426
if REGEXP_OPERATORS.include?(op) && !supports_regexp?
427
raise InvalidOperation, "Pattern matching via regular expressions is not supported on #{db.database_type}"
459
429
sql << PAREN_OPEN
460
430
literal_append(sql, args.at(0))
461
431
sql << SPACE << op.to_s << SPACE
493
463
sql << constant.to_s
496
# SQL fragment specifying an SQL function call
466
# SQL fragment for delayed evaluations, evaluating the
467
# object and literalizing the returned value.
468
def delayed_evaluation_sql_append(sql, callable)
469
literal_append(sql, callable.call)
472
# SQL fragment specifying an emulated SQL function call.
473
# By default, assumes just the function name may need to
474
# be emulated, adapters should set an EMULATED_FUNCTION_MAP
475
# hash mapping emulated functions to native functions in
476
# their dataset class to setup the emulation.
477
def emulated_function_sql_append(sql, f)
478
_function_sql_append(sql, native_function_name(f.f), f.args)
481
# SQL fragment specifying an SQL function call without emulation.
497
482
def function_sql_append(sql, f)
501
sql << FUNCTION_EMPTY
503
literal_append(sql, args)
483
_function_sql_append(sql, f.f, f.args)
507
486
# SQL fragment specifying a JOIN clause without ON or USING.
568
547
literal_append(sql, args[i]) unless i == len
549
unless str.length == args.length || str.length == args.length + 1
550
raise Error, "Mismatched number of placeholders (#{str.length}) and placeholder arguments (#{args.length}) when using placeholder array"
554
match_len = args.length - 1
573
556
previous, q, str = str.partition(QUESTION_MARK)
575
literal_append(sql, args.at(i+=1)) unless q.empty?
558
literal_append(sql, args.at(i+=1)) unless q.empty?
560
unless i == match_len
561
raise Error, "Mismatched number of placeholders (#{i+1}) and placeholder arguments (#{args.length}) when using placeholder array"
579
567
sql << PAREN_CLOSE if pls.parens
624
612
sql << QUOTE << name.to_s.gsub(QUOTE_RE, DOUBLE_QUOTE) << QUOTE
627
# Split the schema information from the table
628
def schema_and_table(table_name)
629
sch = db.default_schema if db
615
# Split the schema information from the table, returning two strings,
616
# one for the schema and one for the table. The returned schema may
617
# be nil, but the table will always have a string value.
619
# Note that this function does not handle tables with more than one
620
# level of qualification (e.g. database.schema.table on Microsoft
622
def schema_and_table(table_name, sch=nil)
623
sch = sch.to_s if sch
632
s, t, a = split_symbol(table_name)
626
s, t, _ = split_symbol(table_name)
634
628
when SQL::QualifiedIdentifier
635
[table_name.table, table_name.column]
629
[table_name.table.to_s, table_name.column.to_s]
636
630
when SQL::Identifier
637
[sch, table_name.value]
631
[sch, table_name.value.to_s]
639
633
[sch, table_name]
639
# Splits table_name into an array of strings.
641
# ds.split_qualifiers(:s) # ['s']
642
# ds.split_qualifiers(:t__s) # ['t', 's']
643
# ds.split_qualifiers(Sequel.qualify(:d, :t__s)) # ['d', 't', 's']
644
# ds.split_qualifiers(Sequel.qualify(:h__d, :t__s)) # ['h', 'd', 't', 's']
645
def split_qualifiers(table_name, *args)
647
when SQL::QualifiedIdentifier
648
split_qualifiers(table_name.table, nil) + split_qualifiers(table_name.column, nil)
650
sch, table = schema_and_table(table_name, *args)
651
sch ? [sch, table] : [table]
645
655
# SQL fragment for specifying subscripts (SQL array accesses)
646
656
def subscript_sql_append(sql, s)
647
657
literal_append(sql, s.f)
648
658
sql << BRACKET_OPEN
649
expression_list_append(sql, s.sub)
659
if s.sub.length == 1 && (range = s.sub.first).is_a?(Range)
660
literal_append(sql, range.begin)
663
e -= 1 if range.exclude_end? && e.is_a?(Integer)
664
literal_append(sql, e)
666
expression_list_append(sql, s.sub)
650
668
sql << BRACKET_CLOSE
739
# Backbone of function_sql_append and emulated_function_sql_append.
740
def _function_sql_append(sql, name, args)
743
sql << FUNCTION_EMPTY
745
literal_append(sql, args)
721
749
# Formats the truncate statement. Assumes the table given has already been
723
751
def _truncate_sql(table)
767
795
options_overlap(COUNT_FROM_SELF_OPTS) ? from_self : unordered
770
def argument_list_append(sql, args)
780
798
# SQL fragment for specifying an alias. expression should already be literalized.
781
799
def as_sql_append(sql, aliaz)
886
# An expression for how to handle an empty array lookup.
868
887
def empty_array_value(op, cols)
869
if Sequel.empty_array_handle_nulls
871
SQL::BooleanExpression.from_value_pairs(c.zip(c), :AND, op == :IN)
873
{1 => ((op == :IN) ? 0 : 1)}
889
SQL::BooleanExpression.from_value_pairs(c.zip(c), :AND, op == :IN)
877
892
# Format the timestamp based on the default_timestamp_format, with a couple
922
937
literal_append(sql, v)
925
alias table_ref_append identifier_append
941
# Append all identifiers in args interspersed by commas.
942
def identifier_list_append(sql, args)
947
identifier_append(sql, a)
927
952
# Modify the identifier returned from the database based on the
928
953
# identifier_output_method.
929
954
def input_identifier(v)
1149
# Get the native function name given the emulated function name.
1150
def native_function_name(emulated_function)
1151
self.class.const_get(:EMULATED_FUNCTION_MAP).fetch(emulated_function, emulated_function)
1130
1154
# Returns a qualified column name (including a table name) if the column
1131
1155
# name isn't already qualified.
1132
1156
def qualified_column_name(column, table)
1133
if Symbol === column
1134
c_table, column, c_alias = split_symbol(column)
1157
if column.is_a?(Symbol)
1158
c_table, column, _ = split_symbol(column)
1290
1314
quote_identifier_append(sql, w[:name])
1291
1315
if args = w[:args]
1292
1316
sql << PAREN_OPEN
1293
argument_list_append(sql, args)
1317
identifier_list_append(sql, args)
1294
1318
sql << PAREN_CLOSE
1311
1335
# Converts an array of source names into into a comma separated list.
1312
1336
def source_list_append(sql, sources)
1313
1337
raise(Error, 'No source specified for query') if sources.nil? || sources == []
1318
identifier_append(sql, s)
1338
identifier_list_append(sql, sources)
1323
# Splits the symbol into three parts. Each part will
1324
# either be a string or nil.
1326
# For columns, these parts are the table, column, and alias.
1327
# For tables, these parts are the schema, table, and alias.
1341
# Delegate to Sequel.split_symbol.
1328
1342
def split_symbol(sym)
1343
Sequel.split_symbol(sym)
1341
1346
# The string that is appended to to create the SQL query, the empty