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 |
ILIKE_0 | = | "(UPPER(".freeze |
ILIKE_1 | = | ") ".freeze |
ILIKE_2 | = | ' UPPER('.freeze |
ILIKE_3 | = | "))".freeze |
LIKE | = | 'LIKE'.freeze |
NOT_LIKE | = | 'NOT LIKE'.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 |
Oracle needs to emulate bitwise operators and ILIKE/NOT ILIKE operators.
# File lib/sequel/adapters/shared/oracle.rb, line 211 211: def complex_expression_sql_append(sql, op, args) 212: case op 213: when :& 214: sql << complex_expression_arg_pairs(args){|a, b| "CAST(BITAND(#{literal(a)}, #{literal(b)}) AS INTEGER)"} 215: when :| 216: sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} - #{complex_expression_sql(:&, [a, b])} + #{literal(b)})"} 217: when :^ 218: sql << complex_expression_arg_pairs(args){|*x| "(#{complex_expression_sql(:|, x)} - #{complex_expression_sql(:&, x)})"} 219: when 'B~''B~' 220: sql << BITCOMP_OPEN 221: literal_append(sql, args.at(0)) 222: sql << BITCOMP_CLOSE 223: when :<< 224: sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * power(2, #{literal b}))"} 225: when :>> 226: sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / power(2, #{literal b}))"} 227: when :% 228: sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"} 229: when :ILIKE, 'NOT ILIKE''NOT ILIKE' 230: sql << ILIKE_0 231: literal_append(sql, args.at(0)) 232: sql << ILIKE_1 233: sql << (op == :ILIKE ? LIKE : NOT_LIKE) 234: sql<< ILIKE_2 235: literal_append(sql, args.at(1)) 236: sql << ILIKE_3 237: else 238: super 239: end 240: 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 245 245: def constant_sql_append(sql, c) 246: if c == :CURRENT_TIME 247: super(sql, :CURRENT_TIMESTAMP) 248: else 249: super 250: end 251: end
Use a custom expression with EXISTS to determine whether a dataset is empty.
# File lib/sequel/adapters/shared/oracle.rb, line 262 262: def empty? 263: db[:dual].where(@opts[:offset] ? exists : unordered.exists).get(1) == nil 264: end
Oracle uses MINUS instead of EXCEPT, and doesn‘t support EXCEPT ALL
# File lib/sequel/adapters/shared/oracle.rb, line 254 254: def except(dataset, opts={}) 255: opts = {:all=>opts} unless opts.is_a?(Hash) 256: raise(Sequel::Error, "EXCEPT ALL not supported") if opts[:all] 257: compound_clone(:minus, dataset, opts) 258: end
Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
# File lib/sequel/adapters/shared/oracle.rb, line 279 279: def select_sql 280: if (limit = @opts[:limit]) && !@opts[:sql] 281: ds = clone(:limit=>nil) 282: # Lock doesn't work in subselects, so don't use a subselect when locking. 283: # Don't use a subselect if custom SQL is used, as it breaks somethings. 284: ds = ds.from_self unless @opts[:lock] 285: sql = @opts[:append_sql] || '' 286: subselect_sql_append(sql, ds.where(SQL::ComplexExpression.new(:<=, ROW_NUMBER_EXPRESSION, limit))) 287: sql 288: else 289: super 290: end 291: end