Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Support for COLLATE in column definitions #24

Merged
2 commits merged into from

2 participants

@jfirebaugh

No description provided.

@jeremyevans
Owner

According to my SQL '92 BNF, collate should come at the end after the constraints:

<column definition> ::=
 <column name> { <data type> | <domain name> }
 [ <default clause> ]
 [ <column constraint definition>... ]
 [ <collate clause> ]

Do you know which databases support this? I don't have a problem enabling it by default, but I'd like an integration or adapter test that shows it works in production in conjunction with the default/null/primary key options.

@jeremyevans
Owner

Looks like MSSQL and MySQL both support collate, and unlike SQL92, have it right after the type:

So this looks like the right way to go for now. If some other database needs it in a different order, it's fairly easy to make adapter specific later. Could you add an adapter spec for MSSQL or MySQL or both using default, not null, unique, and collate at the same time?

@jfirebaugh

I checked MySQL and SQL Server. PostgresSQL doesn't support COLLATE.

In the MySQL documentation, it's actually part of the "data type" production, so before NULL/NOT NULL and DEFAULT:
http://dev.mysql.com/doc/refman/5.0/en/create-table.html

Same position for SQL server:
http://msdn.microsoft.com/en-us/library/ms174979.aspx

In practice, neither DBMS seems to enforce this order. For example, I tried putting COLLATE after DEFAULT and it worked on both.

Where would be the right place to put the integration/adapter test? I looked at integration/schema_test.rb but it seems to be more focused on parsing and schema alterations.

@jfirebaugh

Yep, I'll add adapter specs.

@jfirebaugh

Good to go?

@jeremyevans
Owner

Looks good, running through the test suites now. Assuming no problems I'll push it up.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 2, 2011
  1. Support for COLLATE in column definitions.

    John Firebaugh authored
  2. Add MSSQL and MySQL adapter specs for COLLATE.

    John Firebaugh authored
This page is out of date. Refresh to see the latest.
View
2  CHANGELOG
@@ -1,5 +1,7 @@
=== HEAD
+* Support for COLLATE in column definitions (jfirebaugh)
+
* Don't use a schema when creating a temporary table (jeremyevans)
* Make migrator work correctly when a default_schema is set (jeremyevans) (#331)
View
9 lib/sequel/database/schema_methods.rb
@@ -21,7 +21,7 @@ class Database
UNSIGNED = ' UNSIGNED'.freeze
# The order of column modifiers to use when defining a column.
- COLUMN_DEFINITION_ORDER = [:default, :null, :unique, :primary_key, :auto_increment, :references]
+ COLUMN_DEFINITION_ORDER = [:collate, :default, :null, :unique, :primary_key, :auto_increment, :references]
# Adds a column to the specified table. This method expects a column name,
# a datatype and optionally a hash with additional constraints and options:
@@ -275,7 +275,12 @@ def column_definition_sql(column)
def column_definition_auto_increment_sql(sql, column)
sql << " #{auto_increment_sql}" if column[:auto_increment]
end
-
+
+ # Add collate SQL fragment to column creation SQL.
+ def column_definition_collate_sql(sql, column)
+ sql << " COLLATE #{column[:collate]}" if column[:collate]
+ end
+
# Add default SQL fragment to column creation SQL.
def column_definition_default_sql(sql, column)
sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
View
8 spec/adapters/mssql_spec.rb
@@ -440,3 +440,11 @@ def transaction(opts={})
MSSQL_DB[:items].select(:name, :value).group(:name, :value).order(:name).count.should == 1
end
end
+
+describe "MSSQL::Database#create_table" do
+ specify "should support collate with various other column options" do
+ MSSQL_DB.create_table!(:items){ String :name, :size => 128, :collate => :sql_latin1_general_cp1_ci_as, :default => 'foo', :null => false, :unique => true}
+ MSSQL_DB[:items].insert
+ MSSQL_DB[:items].select_map(:name).should == ["foo"]
+ end
+end
View
6 spec/adapters/mysql_spec.rb
@@ -82,6 +82,12 @@ def logger.method_missing(m, msg)
end
@db.schema(:dolls).map{|k, v| v[:auto_increment]}.should == [nil, nil, true]
end
+
+ specify "should support collate with various other column options" do
+ @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
+ @db[:dolls].insert
+ @db[:dolls].select_map(:name).should == ["foo"]
+ end
end
describe "A MySQL database" do
View
7 spec/core/schema_spec.rb
@@ -281,6 +281,13 @@
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects DEFERRABLE INITIALLY DEFERRED)"]
end
+ specify "should accept collation" do
+ @db.create_table(:cats) do
+ varchar :name, :collate => :utf8_bin
+ end
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(255) COLLATE utf8_bin)"]
+ end
+
specify "should accept inline index definition" do
@db.create_table(:cats) do
integer :id, :index => true
Something went wrong with that request. Please try again.