jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • JRuby
  • JRUBY-1352

ActiveRecord::ConnectionAdapters::JdbcConnection#columns returns empty array on MS SqlServer

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.0.1
  • Fix Version/s: JRuby 1.1RC3
  • Component/s: None
  • Labels:
    None
  • Environment:
    Fedora 7
    JRuby 1.0.1
    ActiveRecord-JDBC 0.5
    Java 6u2
    jtds-1.2

Description

Thank you for developing JRuby and ActiveRecord-JDBC!

When generating scaffold, dumping schema or otherwise trying to list the columns for a table, an empty array is returned.

In the db/schema.rb file all tables are present, but contain no columns.

Any help with this is greatly appreciated.

Uwe Kubosch

  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. File
    database.yml
    14/Sep/07 6:00 AM
    1.0 kB
    Uwe Kubosch

Issue Links

is duplicated by

Bug - A problem which impairs or prevents the functions of the product. JRUBY-1561 Oracle -- ActiveRecord objects that use tables outside the defualt schema do not get their meta data set

  • Major - Major loss of function.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Charles Oliver Nutter added a comment - 19/Oct/07 9:22 PM

We need more information to investigate this. Please try with JRuby trunk and up-to-date ActiveRecord-JDBC and provide more information on the failure. Thanks!

Show
Charles Oliver Nutter added a comment - 19/Oct/07 9:22 PM We need more information to investigate this. Please try with JRuby trunk and up-to-date ActiveRecord-JDBC and provide more information on the failure. Thanks!
Hide
Permalink
Emmanuel Pirsch added a comment - 30/Oct/07 10:16 AM - edited

Here is more information on the issue.

I had the same issue connecting to an axisting table on MS SQL Server.

I had a chat about this on irc://irc.freenode.net/jruby with "nicksieger" on October 30, 2007. You can check the archives.

The issue is that the JDBC adapter tried to look for columns information in the schema that is the same name as the "username" (user used to log into SQL Server). In many situation, the default schema is "dbo".

The thing is that in JdbcAdapterInternalService, there is a different logic to check for a user default schema in the "tables" method than in the "columns_internal" method.

I guess both method should use the same logic to get the default schema if none is specified.

On the other hand, it should probably be nice to be able to add a "schema: schema-name" configuration in database.yml, that the JDBC adapter would use in the "columns" method.

There are two workaround for this problem:

  1. Create a schema with the same name as the user you will use to logon to SQL Server and move the tables in that shema,
  2. Add the following code at the end of environment.rb:
    module JdbcSpec
      module MsSQL
          def columns(table_name, name = nil)
            cc = @connection.columns(table_name.to_s, nil, "dbo") # replace dbo by the schema your tables are in
            cc.each do |col|
              col.identity = true if col.sql_type =~ /identity/i
              col.is_special = true if col.sql_type =~ /text|ntext|image/i
            end
            cc
          end
      end
    end
    
Show
Emmanuel Pirsch added a comment - 30/Oct/07 10:16 AM - edited Here is more information on the issue. I had the same issue connecting to an axisting table on MS SQL Server. I had a chat about this on irc://irc.freenode.net/jruby with "nicksieger" on October 30, 2007. You can check the archives. The issue is that the JDBC adapter tried to look for columns information in the schema that is the same name as the "username" (user used to log into SQL Server). In many situation, the default schema is "dbo". The thing is that in JdbcAdapterInternalService, there is a different logic to check for a user default schema in the "tables" method than in the "columns_internal" method. I guess both method should use the same logic to get the default schema if none is specified. On the other hand, it should probably be nice to be able to add a "schema: schema-name" configuration in database.yml, that the JDBC adapter would use in the "columns" method. There are two workaround for this problem:
  1. Create a schema with the same name as the user you will use to logon to SQL Server and move the tables in that shema,
  2. Add the following code at the end of environment.rb:
    module JdbcSpec
      module MsSQL
          def columns(table_name, name = nil)
            cc = @connection.columns(table_name.to_s, nil, "dbo") # replace dbo by the schema your tables are in
            cc.each do |col|
              col.identity = true if col.sql_type =~ /identity/i
              col.is_special = true if col.sql_type =~ /text|ntext|image/i
            end
            cc
          end
      end
    end
    
Hide
Permalink
Matthew Field added a comment - 16/Nov/07 11:13 AM

This is also a problem in oracle. See the columns method in the normal oracle adaptor for the fix.

Show
Matthew Field added a comment - 16/Nov/07 11:13 AM This is also a problem in oracle. See the columns method in the normal oracle adaptor for the fix.
Hide
Permalink
Matthew Field added a comment - 16/Nov/07 12:32 PM

Here is the patch that I am using for oracle

module ::JdbcSpec
module Oracle
def columns(table_name, name = nil) #:nodoc:

config = ActiveRecord::Base.configurations[RAILS_ENV]
puts config.to_yaml
if /\./.match(table_name)
(owner, table_name) = table_name.split('.')
else
owner = config['username']
end

table_cols = <<-SQL
select column_name as name, data_type as sql_type, data_default, nullable,
decode(data_type, 'NUMBER', data_precision,
'FLOAT', data_precision,
'VARCHAR2', data_length,
'CHAR', data_length,
null) as limit,
decode(data_type, 'NUMBER', data_scale, null) as scale
from all_tab_cols
where owner = '#{owner.upcase}'
and table_name = '#{table_name.upcase}'
order by column_id
SQL

cols = select_all(table_cols, name).map do |row|
limit, scale = row['limit'], row['scale']
if limit || scale
row['sql_type'] << "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
end

  1. clean up odd default spacing from Oracle
    if row['data_default']
    row['data_default'].sub!(/^(.?)\s$/, '\1')
    row['data_default'].sub!(/^'(.*)'$/, '\1')
    row['data_default'] = nil if row['data_default'] =~ /^null$/i
    end

ActiveRecord::ConnectionAdapters::JdbcColumn.new(config,
row['name'].downcase,
row['data_default'],
row['sql_type'],
row['nullable'] == 'Y')

end
cols
end
end
end

Show
Matthew Field added a comment - 16/Nov/07 12:32 PM Here is the patch that I am using for oracle module ::JdbcSpec module Oracle def columns(table_name, name = nil) #:nodoc: config = ActiveRecord::Base.configurations[RAILS_ENV] puts config.to_yaml if /\./.match(table_name) (owner, table_name) = table_name.split('.') else owner = config['username'] end table_cols = <<-SQL select column_name as name, data_type as sql_type, data_default, nullable, decode(data_type, 'NUMBER', data_precision, 'FLOAT', data_precision, 'VARCHAR2', data_length, 'CHAR', data_length, null) as limit, decode(data_type, 'NUMBER', data_scale, null) as scale from all_tab_cols where owner = '#{owner.upcase}' and table_name = '#{table_name.upcase}' order by column_id SQL cols = select_all(table_cols, name).map do |row| limit, scale = row['limit'], row['scale'] if limit || scale row['sql_type'] << "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")") end
  1. clean up odd default spacing from Oracle if row['data_default'] row['data_default'].sub!(/^(.?)\s$/, '\1') row['data_default'].sub!(/^'(.*)'$/, '\1') row['data_default'] = nil if row['data_default'] =~ /^null$/i end
ActiveRecord::ConnectionAdapters::JdbcColumn.new(config, row['name'].downcase, row['data_default'], row['sql_type'], row['nullable'] == 'Y') end cols end end end
Hide
Permalink
Matthew Field added a comment - 16/Nov/07 12:38 PM

Anther try at the code

module ::JdbcSpec
  module Oracle
    def columns(table_name, name = nil) #:nodoc:
      
      config = ActiveRecord::Base.configurations[RAILS_ENV]
      puts config.to_yaml
      if /\./.match(table_name)
        (owner, table_name) = table_name.split('.')
      else
        owner = config['username']
      end
        
      table_cols = <<-SQL
	select column_name as name, data_type as sql_type, data_default, nullable,
	       decode(data_type, 'NUMBER', data_precision,
				 'FLOAT', data_precision,
				 'VARCHAR2', data_length,
				 'CHAR', data_length,
				  null) as limit,
	       decode(data_type, 'NUMBER', data_scale, null) as scale
	  from all_tab_cols
	 where owner      = '#{owner.upcase}'
	   and table_name = '#{table_name.upcase}'
	 order by column_id
      SQL

      cols = select_all(table_cols, name).map do |row|
	limit, scale = row['limit'], row['scale']
	if limit || scale
	  row['sql_type'] << "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
	end

	# clean up odd default spacing from Oracle
	if row['data_default']
	  row['data_default'].sub!(/^(.*?)\s*$/, '\1')
	  row['data_default'].sub!(/^'(.*)'$/, '\1')
	  row['data_default'] = nil if row['data_default'] =~ /^null$/i
	end

        
	ActiveRecord::ConnectionAdapters::JdbcColumn.new(config,
                         row['name'].downcase,
			 row['data_default'],
			 row['sql_type'],
			 row['nullable'] == 'Y')
        
      end
      cols
    end
  end
end
Show
Matthew Field added a comment - 16/Nov/07 12:38 PM Anther try at the code
module ::JdbcSpec
  module Oracle
    def columns(table_name, name = nil) #:nodoc:
      
      config = ActiveRecord::Base.configurations[RAILS_ENV]
      puts config.to_yaml
      if /\./.match(table_name)
        (owner, table_name) = table_name.split('.')
      else
        owner = config['username']
      end
        
      table_cols = <<-SQL
	select column_name as name, data_type as sql_type, data_default, nullable,
	       decode(data_type, 'NUMBER', data_precision,
				 'FLOAT', data_precision,
				 'VARCHAR2', data_length,
				 'CHAR', data_length,
				  null) as limit,
	       decode(data_type, 'NUMBER', data_scale, null) as scale
	  from all_tab_cols
	 where owner      = '#{owner.upcase}'
	   and table_name = '#{table_name.upcase}'
	 order by column_id
      SQL

      cols = select_all(table_cols, name).map do |row|
	limit, scale = row['limit'], row['scale']
	if limit || scale
	  row['sql_type'] << "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
	end

	# clean up odd default spacing from Oracle
	if row['data_default']
	  row['data_default'].sub!(/^(.*?)\s*$/, '\1')
	  row['data_default'].sub!(/^'(.*)'$/, '\1')
	  row['data_default'] = nil if row['data_default'] =~ /^null$/i
	end

        
	ActiveRecord::ConnectionAdapters::JdbcColumn.new(config,
                         row['name'].downcase,
			 row['data_default'],
			 row['sql_type'],
			 row['nullable'] == 'Y')
        
      end
      cols
    end
  end
end
Hide
Permalink
Joern Barthel added a comment - 13/Feb/08 4:56 PM

@Uwe - please try to log in as 'sa' and see if .columns returns the expected values. On sqlserver it might be a permission problem.

Show
Joern Barthel added a comment - 13/Feb/08 4:56 PM @Uwe - please try to log in as 'sa' and see if .columns returns the expected values. On sqlserver it might be a permission problem.
Hide
Permalink
Uwe Kubosch added a comment - 14/Feb/08 5:11 AM

I tried dumping the database yesterday using activerecord-jdbc-adapter 0.7.2 and it worked!

However, all table names were converted to lower case. This is bad since the primary use of the database is a Java application that accesses using camel case table names.

Can you look at that, or should I file a separate issue for this?

Show
Uwe Kubosch added a comment - 14/Feb/08 5:11 AM I tried dumping the database yesterday using activerecord-jdbc-adapter 0.7.2 and it worked! However, all table names were converted to lower case. This is bad since the primary use of the database is a Java application that accesses using camel case table names. Can you look at that, or should I file a separate issue for this?
Hide
Permalink
Charles Oliver Nutter added a comment - 17/Mar/08 8:46 PM

Please file a bug for the separate issues. Thank you!

Show
Charles Oliver Nutter added a comment - 17/Mar/08 8:46 PM Please file a bug for the separate issues. Thank you!

People

  • Assignee:
    Charles Oliver Nutter
    Reporter:
    Uwe Kubosch
Vote (1)
Watch (3)

Dates

  • Created:
    14/Sep/07 6:00 AM
    Updated:
    25/Aug/09 11:30 AM
    Resolved:
    17/Mar/08 8:46 PM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.