Module | Sequel::Oracle::DatasetMethods |
In: |
lib/sequel/adapters/shared/oracle.rb
|
SELECT_CLAUSE_METHODS | = | Dataset.clause_methods(:select, %w'with select distinct columns from join where group having compounds order lock') |
ROW_NUMBER_EXPRESSION | = | LiteralString.new('ROWNUM').freeze |
SPACE | = | Dataset::SPACE |
APOS | = | Dataset::APOS |
APOS_RE | = | Dataset::APOS_RE |
DOUBLE_APOS | = | Dataset::DOUBLE_APOS |
FROM | = | Dataset::FROM |
BITCOMP_OPEN | = | "((0 - ".freeze |
BITCOMP_CLOSE | = | ") - 1)".freeze |
TIMESTAMP_FORMAT | = | "TIMESTAMP '%Y-%m-%d %H:%M:%S%N %z'".freeze |
TIMESTAMP_OFFSET_FORMAT | = | "%+03i:%02i".freeze |
BOOL_FALSE | = | "'N'".freeze |
BOOL_TRUE | = | "'Y'".freeze |
HSTAR | = | "H*".freeze |
DUAL | = | ['DUAL'.freeze].freeze |
# File lib/sequel/adapters/shared/oracle.rb, line 247 247: def complex_expression_sql_append(sql, op, args) 248: case op 249: when :& 250: sql << complex_expression_arg_pairs(args){|a, b| "CAST(BITAND(#{literal(a)}, #{literal(b)}) AS INTEGER)"} 251: when :| 252: sql << complex_expression_arg_pairs(args) do |a, b| 253: s1 = '' 254: complex_expression_sql_append(s1, :&, [a, b]) 255: "(#{literal(a)} - #{s1} + #{literal(b)})" 256: end 257: when :^ 258: sql << complex_expression_arg_pairs(args) do |*x| 259: s1 = '' 260: s2 = '' 261: complex_expression_sql_append(s1, :|, x) 262: complex_expression_sql_append(s2, :&, x) 263: "(#{s1} - #{s2})" 264: end 265: when 'B~''B~' 266: sql << BITCOMP_OPEN 267: literal_append(sql, args.at(0)) 268: sql << BITCOMP_CLOSE 269: when :<< 270: sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * power(2, #{literal(b)}))"} 271: when :>> 272: sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / power(2, #{literal(b)}))"} 273: when :% 274: sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"} 275: else 276: super 277: end 278: end
Oracle doesn‘t support CURRENT_TIME, as it doesn‘t have a type for storing just time values without a date, so use CURRENT_TIMESTAMP in its place.
# File lib/sequel/adapters/shared/oracle.rb, line 283 283: def constant_sql_append(sql, c) 284: if c == :CURRENT_TIME 285: super(sql, :CURRENT_TIMESTAMP) 286: else 287: super 288: end 289: end
Use a custom expression with EXISTS to determine whether a dataset is empty.
# File lib/sequel/adapters/shared/oracle.rb, line 313 313: def empty? 314: db[:dual].where(@opts[:offset] ? exists : unordered.exists).get(1) == nil 315: end
Oracle treats empty strings like NULL values, and doesn‘t support char_length, so make char_length use length with a nonempty string. Unfortunately, as Oracle treats the empty string as NULL, there is no way to get trim to return an empty string instead of nil if the string only contains spaces.
# File lib/sequel/adapters/shared/oracle.rb, line 296 296: def emulated_function_sql_append(sql, f) 297: case f.f 298: when :char_length 299: literal_append(sql, Sequel::SQL::Function.new(:length, Sequel.join([f.args.first, 'x'])) - 1) 300: else 301: super 302: end 303: end
Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
# File lib/sequel/adapters/shared/oracle.rb, line 330 330: def select_sql 331: if (limit = @opts[:limit]) && !@opts[:sql] 332: ds = clone(:limit=>nil) 333: # Lock doesn't work in subselects, so don't use a subselect when locking. 334: # Don't use a subselect if custom SQL is used, as it breaks somethings. 335: ds = ds.from_self unless @opts[:lock] 336: sql = @opts[:append_sql] || '' 337: subselect_sql_append(sql, ds.where(SQL::ComplexExpression.new(:<=, ROW_NUMBER_EXPRESSION, limit))) 338: sql 339: else 340: super 341: end 342: end