ActiveRecord 2.1 Migration support

Hi all,

I am in the process of adding Migration support to the Ingres
ActiveRecord adapter and have run in to a problem. During the call to
create_table the Ingres adapter some how causes ruby to blow the stack
and coredump/segv. I have tracked down the problem down to
“add_column_options!” in
“lib/active_record/connection_adapters/abstract/schema_statements.rb”.
Specifically the following line never gets executed:

sql << " DEFAULT #{quote(options[:default], options[:column])}" if
options_include_default?(options)

As a result the code keeps looping . Comparing the contents of “options”
for MySQL and Ingres I don’t see anything of any significance that would
cause the call not to work. Below is a dump of “options” using
ruby-debug:

MySQL
{:default=>nil,
:column=>#<struct ActiveRecord::ConnectionAdapters::ColumnDefinition
base=#<ActiveRecord::ConnectionAdapters::MysqlAdapter:0xb6fc6f50
@logger=#<ActiveSupport::BufferedLogger:0xb70935f0
@log=#<File:/home/grant/stuff/ruby/rails/auction-demo-mysql/log/development.log>,
@no_block=false,
@auto_flushing=1,
@buffer=[],
@level=0>,
@runtime=0.134179830551147,
@quoted_column_names={“unique_schema_migrations”=>"unique_schema_migrations",
“schema_migrations”=>"schema_migrations",
“id”=>"id",
“auctions”=>"auctions",
:version=>"version",
:title=>"title"},
@connection=#Mysql:0xb6fc8418,
@connection_options=[nil,
“root”,
“”,
“auction_development”,
nil,
nil],
@config={:allow_concurrency=>false,
:adapter=>“mysql”,
:database=>“auction_development”},
@query_cache_enabled=false,
@last_verification=0,
@quoted_table_names={“schema_migrations”=>"schema_migrations",
“auctions”=>"auctions"}>,
name=:title,
type=“string”,
limit=255,
precision=nil,
scale=nil,
default=nil,
null=nil>,
:null=>nil}

Ingres
{:default=>nil,
:column=>#<struct ActiveRecord::ConnectionAdapters::ColumnDefinition
base=#<ActiveRecord::ConnectionAdapters::IngresAdapter:0xb7004f80
@primary_key=nil,
@logger=#<ActiveSupport::BufferedLogger:0xb70ceb3c
@log=#<File:/home/grant/stuff/ruby/rails/auction-demo/log/development.log>,
@no_block=false,
@auto_flushing=1,
@buffer=[],
@level=0>,
@runtime=0.0605983734130859,
@connection=#Ingres:0xb7005084,
@query_cache_enabled=false,
@last_verification=0>,
name=:title,
type=“string”,
limit=nil,
precision=nil,
scale=nil,
default=nil,
null=nil>,
:null=>nil}

I was wondering if anyone, had come across something similar when
writing and adapter for ActiveRecord for another database engine. Or if
anyone can point out some things I can try it would be greatly
appreciated

regads

grant


Grant Croker - Ingres PHP, Ruby and Python maintainer
I refuse to answer that question on the grounds that I don’t know
the answer.

  • (Zaphod B.)

On 24 Jun 2008, at 15:19, Grant Croker wrote:

sql << " DEFAULT #{quote(options[:default], options[:column])}" if
options_include_default?(options)

As a result the code keeps looping . Comparing the contents of
“options”
for MySQL and Ingres I don’t see anything of any significance that
would
cause the call not to work. Below is a dump of “options” using ruby-
debug:

You might get more responses over on the rubyonrails-core list.

Fred

Reposting here (was sent to rubyonrails-talk)

On/El 24/06/08 16:19, Grant Croker
wrote/escribió:> Hi all,

options_include_default?(options)
@logger=#<ActiveSupport::BufferedLogger:0xb70935f0
“id”=>"id",
@config={:allow_concurrency=>false,
scale=nil,
@log=#<File:/home/grant/stuff/ruby/rails/auction-demo/log/development.log>,
type=“string”,
appreciated

regads

grant


Grant Croker - Ingres PHP, Ruby and Python maintainer
I refuse to answer that question on the grounds that I don’t know
the answer.

  • (Zaphod B.)

On/El 24/06/08 17:01, Frederick C. wrote/escribió:

On 24 Jun 2008, at 15:19, Grant Croker wrote:

You might get more responses over on the rubyonrails-core list.

Fred

thanks


Grant Croker - Ingres PHP, Ruby and Python maintainer
I refuse to answer that question on the grounds that I don’t know
the answer.

  • (Zaphod B.)

On 24 Jun 2008, at 16:17, Grant Croker wrote:

“add_column_options!” in
of
“options” using ruby-debug:

As in options_include_default? returns false ? Even if that were to be
the case I’m not sure why that would cause a crash, I would expect
things to work (with the caveat that no column defaults would be set).

Fred

On/El 25/06/08 10:43, Frederick C. wrote/escribió:

As in options_include_default? returns false ? Even if that were to be
the case I’m not sure why that would cause a crash, I would expect
things to work (with the caveat that no column defaults would be set).

The crash occurs due to the looping/recursion as it eventually runs out
of stack space in the process. See http://en.pastebin.ca/raw/1055724 for
the backtrace I get when running rake using --trace. You will see from
the log file that it continually loops against the following 4 lines:

activerecord-2.1.0/lib/active_record/connection_adapters/ingres_adapter.rb:398:in
quote' activerecord-2.1.0/lib/active_record/connection_adapters/abstract/schema_statements.rb:377:in add_column_options!’
activerecord-2.1.0/lib/active_record/connection_adapters/abstract/schema_definitions.rb:272:in
add_column_options!' activerecord-2.1.0/lib/active_record/connection_adapters/abstract/schema_definitions.rb:263:in to_s’

I am not quite sure it ever calls quote from ingres_adapter.rb since
ruby-debug does not stop in that function. Any “puts” tracing in that
function is never called so I can only assume it never gets called but
as far as I can tell the condtiions for options_include_default? with
MySQL and Ingres are the same…

grant


Grant Croker - Ingres PHP, Ruby and Python maintainer
Mark Carwardine’s role, essentially, was to be the one who knew what he
was talking about. My role, and one for which I was entirely qualified,
was to be an extremely ignorant non-zoologist to whom everything that
happened would come as a complete surprise.

On 25 Jun 2008, at 14:58, Grant Croker wrote:

As in options_include_default? returns false ? Even if that were to
see from the log file that it continually loops against the
following 4 lines:
activerecord-2.1.0/lib/active_record/connection_adapters/
ingres_adapter.rb:398:in quote' activerecord-2.1.0/lib/active_record/connection_adapters/abstract/ schema_statements.rb:377:inadd_column_options!’
activerecord-2.1.0/lib/active_record/connection_adapters/abstract/
schema_definitions.rb:272:in add_column_options!' activerecord-2.1.0/lib/active_record/connection_adapters/abstract/ schema_definitions.rb:263:into_s’

Hmm, ColumnDefinition aliases to_s to to_sql (and then that calls
through to add_column_options!, which calls through to
add_column_options! on the adapter itself). Are you calling to_s on
something you shouldn’t be (perhaps as a debugging aid?)

Fred

On/El 25/06/08 16:33, Frederick C. wrote/escribió:

activerecord-2.1.0/lib/active_record/connection_adapters/abstract/

I found the recursive problem - the ingres adapter method quote() makes
the following call to a trace function:
complete_trace(" in quote(#{value}, #{column}) ")

which goes to:

def complete_trace (msg)
if(PRINT_TRACES) then
puts “\n#{msg}\n”
end
end

commenting out that line allows the migration to carry on, at least it
creates the tables now.

It would appear that even when PRINT_TRACES == false that the msg
(quote(#{value}, #{column})) is being executed. Can you think of a
reason why that would be?

thanks

grant


Grant Croker - Ingres PHP, Ruby and Python maintainer
Mark Carwardine’s role, essentially, was to be the one who knew what he
was talking about. My role, and one for which I was entirely qualified,
was to be an extremely ignorant non-zoologist to whom everything that
happened would come as a complete surprise.

On 25 Jun 2008, at 17:34, Grant Croker wrote:

schema_statements.rb:377:in `add_column_options!’

end

commenting out that line allows the migration to carry on, at least
it creates the tables now.

It would appear that even when PRINT_TRACES == false that the msg
(quote(#{value}, #{column})) is being executed. Can you think of a
reason why that would be?

It’s the column.to_s which is bad, and that bit has to be evaluated
(even if complete_trace then ignores it). You’ll be ok if you change
#{column} to something else

Fred

On/El 25/06/08 18:46, Frederick C. wrote/escribió:

Fred

That makes sense - thanks for your help

grant


Grant Croker - Ingres PHP, Ruby and Python maintainer
Mark Carwardine’s role, essentially, was to be the one who knew what he
was talking about. My role, and one for which I was entirely qualified,
was to be an extremely ignorant non-zoologist to whom everything that
happened would come as a complete surprise.