NoMethodError: undefined method `*' for nil:NilClass: SELECT "SW_SERVICE".* FROM .......

462 views
Skip to first unread message

Brian Ploetz

unread,
Dec 13, 2010, 9:44:11 PM12/13/10
to Oracle enhanced adapter for ActiveRecord
Environment:
Ruby 1.9.2
Rails 3.0.3
Oracle Enhanced Adapter 1.3.1
Ruby OCI 8 2.0.4

I'm getting the following error on one of my QA machines (Ubuntu
10.04), where the same exact code works locally on my desktop (Mac
OSX). Any idea what could cause this?

Service Load (1.6ms) SELECT "SW_SERVICE".* FROM "SW_SERVICE" WHERE
(namespace = 'SW') AND ROWNUM <= 1
NoMethodError: undefined method `*' for nil:NilClass: SELECT
"SW_SERVICE".* FROM "SW_SERVICE" WHERE (namespace = 'SW') AND ROWNUM
<= 1
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract_adapter.rb:202:in `rescue
in log'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract_adapter.rb:194:in `log'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-oracle_enhanced-
adapter-1.3.1/lib/active_record/connection_adapters/
oracle_enhanced_adapter.rb:948:in `log'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-oracle_enhanced-
adapter-1.3.1/lib/active_record/connection_adapters/
oracle_enhanced_adapter.rb:906:in `select'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract/database_statements.rb:7:in
`select_all'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract/query_cache.rb:54:in `block
in select_all'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract/query_cache.rb:68:in
`cache_sql'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract/query_cache.rb:54:in
`select_all'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/base.rb:467:in `find_by_sql'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/relation.rb:64:in `to_a'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/relation/finder_methods.rb:333:in `find_first'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/relation/finder_methods.rb:122:in `first'
/app/sw-api/releases/20101213215753/app/controllers/
users_controller.rb:35:in `create'

Raimonds Simanovskis

unread,
Dec 14, 2010, 2:14:49 AM12/14/10
to oracle-...@googlegroups.com
Based on error message I can see that somewhere multiplication method (*) is being called on nil object.

To find out where exactly it is happening please edit /app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/ 
active_record/connection_adapters/abstract_adapter.rb starting from line 199 and comment out

        # rescue Exception => e
        #   message = "#{e.class.name}: #{e.message}: #{sql}"
        #   @logger.debug message if @logger
        #   raise translate_exception(e, message)

In this way in error stack trace you will see exact place where this issue is happening (now it is rescued by this code block).

Raimonds

Brian Ploetz

unread,
Dec 14, 2010, 9:41:17 AM12/14/10
to Oracle enhanced adapter for ActiveRecord
I just printed out the backtrace of that Exception. Here's what I see:

ROOT CAUSE:
/app/sw-api/shared/bundle/ruby/1.9.1/gems/ruby-oci8-2.0.4/lib/oci8/
datetime.rb:193:in `ocitimestamp_to_time'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/ruby-oci8-2.0.4/lib/oci8/
datetime.rb:268:in `get'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-oracle_enhanced-
adapter-1.3.1/lib/active_record/connection_adapters/
oracle_enhanced_oci_connection.rb:110:in `fetch'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-oracle_enhanced-
adapter-1.3.1/lib/active_record/connection_adapters/
oracle_enhanced_oci_connection.rb:110:in `select'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-oracle_enhanced-
adapter-1.3.1/lib/active_record/connection_adapters/
oracle_enhanced_adapter.rb:907:in `block in select'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract_adapter.rb:197:in `block in
log'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activesupport-3.0.3/lib/
active_support/notifications/instrumenter.rb:21:in `instrument'
/app/sw-api/shared/bundle/ruby/1.9.1/gems/activerecord-3.0.3/lib/
active_record/connection_adapters/abstract_adapter.rb:195:in `log'
/app/sw-api/releases/20101214143730/app/controllers/
users_controller.rb:35:in `create'



On Dec 14, 2:14 am, Raimonds Simanovskis

Brian Ploetz

unread,
Dec 14, 2010, 9:53:22 AM12/14/10
to Oracle enhanced adapter for ActiveRecord
I should also point out that this is failing against an 11g database,
but it works against a 10g database with the same schema. Not sure if
date/time handling has changed in 11g or not, but figured I'd mention
it......

Brian Ploetz

unread,
Dec 14, 2010, 9:59:58 AM12/14/10
to Oracle enhanced adapter for ActiveRecord
And here's my Rails initializer for the adapter config:

# config/initializers/oracle.rb
ENV['TZ'] = 'US/Eastern'

ActiveSupport.on_load(:active_record) do
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval
do
self.emulate_integers_by_column_name = true
self.emulate_dates_by_column_name = true
self.emulate_booleans_from_strings = false

# set string to date format if using e.g. calendar helpers

# self.string_to_date_format = "%d.%m.%Y"
# self.string_to_time_format = "%d.%m.%Y %H:%M:%S"

# Cache column descriptions between requests.
# Highly recommended as currently Arel is doing a lot of
additional queries
# to get table columns and primary key.
# If this is used then you need to restart server after running
migrations which change table columns.
# By default caching is enabled just in test and production
environments.
self.cache_columns = true
end
end

Brian Ploetz

unread,
Dec 14, 2010, 12:28:28 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
Here's the code in ruby-oci8-2.0.4/lib/oci8/datetime.rb it's failing
on:

if @@time_new_accepts_timezone

# after ruby 1.9.2
def ocitimestamp_to_time(ary)
return nil if ary.nil?

year, month, day, hour, minute, sec, fsec, tz_hour, tz_min
= ary

sec += fsec / Rational(1000000000)
HERE ---> utc_offset = tz_hour * 3600 + tz_min * 60
return ::Time.new(year, month, day, hour, minute, sec,
utc_offset)
end

else


Given that the error is "undefined method `*' for nil:NilClass", I'm
assuming it's that tz_hour object that's nil. So it seems like
something related to timezones is messing this up. The columns in
question are defined as DATE:

START_DATE NOT NULL DATE
END_DATE DATE

And I've told the Oracle Adapter "emulate_dates_by_column_name =
true", which according to the documentation should treat these
properties as Date objects, not Time objects. So the question is is
there some configuration I can set to disable timezone handling
altogether to avoid this, or is this a bug in either the Oracle
Adapter or the ruby-oci8 gem?

Let me know if you need more info. Thanks!
BP

Raimonds Simanovskis

unread,
Dec 14, 2010, 5:18:38 PM12/14/10
to oracle-...@googlegroups.com
This seems like ruby-oci8 issue which happens in your specific case when using Ruby 1.9.2 with Oracle 11g.

Can you try the following in plain irb session (using Ruby 1.9.2) to verify if you can repeat this issue (replace username/password/database_name according to your Oracle 11g connection):

require "rubygems"
gem "ruby-oci8"
require "oci8"
conn = OCI8.new "username", "password", "database_name"
conn.select_one("SELECT current_timestamp from dual").first

This should get current timestamp from Oracle and convert it to Ruby Time object (and I assume it should use the same code that is failing in your case).

And also - which exact Oracle client have you installed?

Raimonds

Brian Ploetz

unread,
Dec 14, 2010, 5:37:24 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
Hi Raimonds,

Here's the result of this test using ruby-oci8 directly:

$ irb
ruby-1.9.2-p0 > require 'rubygems'
=> true
ruby-1.9.2-p0 > gem 'ruby-oci8'
=> true
ruby-1.9.2-p0 > require 'oci8'
=> true
ruby-1.9.2-p0 > conn = OCI8.new "XXXX", "XXXX", "XXXX"
=> #<OCI8:XXXX>
ruby-1.9.2-p0 > result = conn.select_one("SELECT current_timestamp
from dual").first
=> 2010-12-14 16:29:42 -0600
ruby-1.9.2-p0 > puts result.class
Time

And when I try to query the DATE column in the table in question, I
get.....

ruby-1.9.2-p0 > result = conn.select_one("SELECT start_date from
SW_SERVICE where namespace = 'SW'").first
=> 2004-11-14 00:00:00 -0600
ruby-1.9.2-p0 > puts result.class
Time

....as you can see neither fails and both return a Time object.

I'm using the full 64 bit 11.2 client.

Thanks for your help.
BP


On Dec 14, 5:18 pm, Raimonds Simanovskis

Raimonds Simanovskis

unread,
Dec 14, 2010, 6:02:03 PM12/14/10
to oracle-...@googlegroups.com
OK, to simulate what oracle_enhanced adapter is doing you can try

require "rubygems"
gem "ruby-oci8"
require "oci8"
ENV['TZ'] = 'US/Eastern'
conn = OCI8.new "username", "password", "database_name"
conn.exec "alter session set time_zone = '#{ENV['TZ']}'"
cursor = conn.exec "SELECT \"SW_SERVICE\".* FROM \"SW_SERVICE\" WHERE (namespace = 'SW') AND ROWNUM <= 1"
cursor.fetch

Other thing that you can try is to use Oracle Instant Client version 10.2.0.4 (from http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html). I am everywhere using this older version as it provides all necessary functionality and can be used with 11g database as well.

Brian Ploetz

unread,
Dec 14, 2010, 6:15:41 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
Bingo:

deploy@web1:~$ irb
ruby-1.9.2-p0 > require "rubygems"
=> true
ruby-1.9.2-p0 > gem "ruby-oci8"
=> true
ruby-1.9.2-p0 > require "oci8"
=> true
ruby-1.9.2-p0 > ENV['TZ'] = 'US/Eastern'
=> "US/Eastern"
ruby-1.9.2-p0 > conn = OCI8.new "XXXX", "XXXX", "XXXX"
=> #<OCI8:XXXX>
ruby-1.9.2-p0 > conn.exec "alter session set time_zone =
'#{ENV['TZ']}'"
=> 0
ruby-1.9.2-p0 > cursor = conn.exec "SELECT \"SW_SERVICE\".* FROM
\"SW_SERVICE\" WHERE
ruby-1.9.2-p0"> (namespace = 'SW') AND ROWNUM <= 1"
=> #<OCI8::Cursor:0x00000001836e08>
ruby-1.9.2-p0 > cursor.fetch
NoMethodError: undefined method `*' for nil:NilClass
from /usr/local/rvm/gems/ruby-1.9.2-p0/gems/ruby-oci8-2.0.4/lib/oci8/
datetime.rb:193:in `ocitimestamp_to_time'
from /usr/local/rvm/gems/ruby-1.9.2-p0/gems/ruby-oci8-2.0.4/lib/oci8/
datetime.rb:268:in `get'
from (irb):9:in `fetch'
from (irb):9
from /usr/local/rvm/rubies/ruby-1.9.2-p0/bin/irb:16:in `<main>'



On Dec 14, 6:02 pm, Raimonds Simanovskis
<raimonds.simanovs...@gmail.com> wrote:
> OK, to simulate what oracle_enhanced adapter is doing you can try
>
> require "rubygems"
> gem "ruby-oci8"
> require "oci8"
> ENV['TZ'] = 'US/Eastern'
> conn = OCI8.new "username", "password", "database_name"
> conn.exec "alter session set time_zone = '#{ENV['TZ']}'"
> cursor = conn.exec "SELECT \"SW_SERVICE\".* FROM \"SW_SERVICE\" WHERE
> (namespace = 'SW') AND ROWNUM <= 1"
> cursor.fetch
>
> Other thing that you can try is to use Oracle Instant Client version
> 10.2.0.4
> (fromhttp://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html).

Raimonds Simanovskis

unread,
Dec 14, 2010, 6:20:35 PM12/14/10
to oracle-...@googlegroups.com
OK, now we now that it is ruby-oci8 fault :)

You can investigate it further trying different time zone settings to identify if it is causing this issue. As well try maybe Oracle Instant Client 10.2.0.4 and see if it happens with that client as well.

Lastly it would be nice to report this issue (with description how to reproduce it as well as with link to this thread) at ruby-oci8 help forum http://rubyforge.org/forum/forum.php?forum_id=1078

But maybe ruby-oci8 maintainer Kubo will notice it here as well as he is subscribed to this forum as well.

Raimonds

Brian Ploetz

unread,
Dec 14, 2010, 6:20:47 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
Removing the "alter session set time_zone = '#{ENV['TZ']}'" eliminates
the exception:

deploy@web1:~$ irb
ruby-1.9.2-p0 > require "rubygems"
=> true
ruby-1.9.2-p0 > gem "ruby-oci8"
=> true
ruby-1.9.2-p0 > require "oci8"
=> true
ruby-1.9.2-p0 > conn = OCI8.new "XXXX", "XXXX", "XXXX"
=> #<OCI8:XXXX>
ruby-1.9.2-p0 > cursor = conn.exec "SELECT \"SW_SERVICE\".* FROM
\"SW_SERVICE\" WHERE
ruby-1.9.2-p0"> (namespace = 'SW') AND ROWNUM <= 1"
=> #<OCI8::Cursor:0x00000001eabb80>
ruby-1.9.2-p0 > cursor.fetch
=> [3, "/sw/", "SW", "Y", 2004-11-14 00:00:00 -0600, 2025-12-31
00:00:00 -0600]

Brian Ploetz

unread,
Dec 14, 2010, 6:22:18 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
Will do. Thanks so much for your help Raimonds!


On Dec 14, 6:20 pm, Raimonds Simanovskis
<raimonds.simanovs...@gmail.com> wrote:
> OK, now we now that it is ruby-oci8 fault :)
>
> You can investigate it further trying different time zone settings to
> identify if it is causing this issue. As well try maybe Oracle Instant
> Client 10.2.0.4 and see if it happens with that client as well.
>
> Lastly it would be nice to report this issue (with description how to
> reproduce it as well as with link to this thread) at ruby-oci8 help forumhttp://rubyforge.org/forum/forum.php?forum_id=1078

Raimonds Simanovskis

unread,
Dec 14, 2010, 6:22:39 PM12/14/10
to oracle-...@googlegroups.com
And also investigate which exact DATE value in SW_SERVICE table is causing this issue (try to select individual columns and also try selecting different rows) - I remember that once I was solving problem with damaged DATE value in database which was giving strange errors.

Raimonds

Brian Ploetz

unread,
Dec 14, 2010, 6:50:08 PM12/14/10
to Oracle enhanced adapter for ActiveRecord
FYI, removing ALL timezone configuration from my app, i.e. this in the
intitializer....

ENV['TZ'] = 'US/Eastern'

...and this in the database.yml....

time_zone: US/Eastern

....causes that "alter session set time_zone = '#{ENV['TZ']}'"
statement NOT to be called, and thus avoids the bug. From
oracle_enhanced_oci_connection.rb:

time_zone = config[:time_zone] || ENV['TZ']
conn.exec "alter session set time_zone = '#{time_zone}'"
unless time_zone.blank?
Reply all
Reply to author
Forward
0 new messages