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

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:

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ó:

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


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

thanks

Reposting here (was sent to rubyonrails-talk)

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

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:

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 Cheung wrote/escribió:

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:
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 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:
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

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

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:

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'

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 Cheung wrote/escribió:

 The crash occurs due to the looping/recursion as it eventually runs out of stack space in the process. See 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'
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?)

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

``

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

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'

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?)

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?

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 Cheung wrote/escribió:

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

That makes sense - thanks for your help

grant