Skip to content

Commit 060f488

Browse files
committed
Add support for collation in Myxql
1 parent 63dfb83 commit 060f488

File tree

2 files changed

+83
-10
lines changed

2 files changed

+83
-10
lines changed

integration_test/myxql/migrations_test.exs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,30 @@ defmodule Ecto.Integration.MigrationsTest do
2929
end
3030
end
3131

32+
text_types = ~w/tinytext text mediumtext longtext/a
33+
@text_types text_types
34+
35+
defmodule CollateMigration do
36+
use Ecto.Migration
37+
38+
@text_types text_types
39+
def change do
40+
create table(:collate) do
41+
add :string, :string, collation: "utf8mb4_bin"
42+
add :varchar, :varchar, size: 255, collation: "utf8mb4_bin"
43+
add :integer, :integer, collation: "utf8mb4_bin"
44+
45+
for type <- @text_types do
46+
add type, type, collation: "utf8mb4_bin"
47+
end
48+
end
49+
50+
alter table(:collate) do
51+
modify :string, :string, collation: "utf8mb4_general_ci"
52+
end
53+
end
54+
end
55+
3256
describe "Migrator" do
3357
@get_lock_command ~s[SELECT GET_LOCK('ecto_Ecto.Integration.PoolRepo', -1)]
3458
@release_lock_command ~s[SELECT RELEASE_LOCK('ecto_Ecto.Integration.PoolRepo')]
@@ -107,5 +131,34 @@ defmodule Ecto.Integration.MigrationsTest do
107131

108132
assert log =~ "ALTER TABLE `alter_table` ADD `column2` varchar(255) COMMENT 'second column' AFTER `column1`"
109133
end
134+
135+
test "collation can be set on a column" do
136+
num = @base_migration + System.unique_integer([:positive])
137+
assert :ok = Ecto.Migrator.up(PoolRepo, num, CollateMigration, log: :info)
138+
query = fn column -> """
139+
SELECT collation_name
140+
FROM information_schema.columns
141+
WHERE table_name = 'collate' AND column_name = '#{column}';
142+
"""
143+
end
144+
145+
assert %{
146+
rows: [["utf8mb4_general_ci"]]
147+
} = Ecto.Adapters.SQL.query!(PoolRepo, query.("string"), [])
148+
149+
assert %{
150+
rows: [["utf8mb4_bin"]]
151+
} = Ecto.Adapters.SQL.query!(PoolRepo, query.("text"), [])
152+
153+
for type <- @text_types do
154+
assert %{
155+
rows: [["utf8mb4_bin"]]
156+
} = Ecto.Adapters.SQL.query!(PoolRepo, query.(to_string(type)), [])
157+
end
158+
159+
assert %{
160+
rows: [[nil]]
161+
} = Ecto.Adapters.SQL.query!(PoolRepo, query.("integer"), [])
162+
end
110163
end
111164
end

lib/ecto/adapters/myxql/connection.ex

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,13 +1171,13 @@ if Code.ensure_loaded?(MyXQL) do
11711171
quote_name(name),
11721172
?\s,
11731173
reference_column_type(ref.type, opts),
1174-
column_options(opts),
1174+
column_options(ref.type, opts),
11751175
reference_expr(ref, table, name)
11761176
]
11771177
end
11781178

11791179
defp column_definition(_table, {:add, name, type, opts}) do
1180-
[quote_name(name), ?\s, column_type(type, opts), column_options(opts)]
1180+
[quote_name(name), ?\s, column_type(type, opts), column_options(type, opts)]
11811181
end
11821182

11831183
defp column_changes(table, columns) do
@@ -1194,13 +1194,13 @@ if Code.ensure_loaded?(MyXQL) do
11941194
quote_name(name),
11951195
?\s,
11961196
reference_column_type(ref.type, opts),
1197-
column_options(opts),
1197+
column_options(ref.type, opts),
11981198
constraint_expr(ref, table, name)
11991199
]
12001200
end
12011201

12021202
defp column_change(_table, {:add, name, type, opts}) do
1203-
["ADD ", quote_name(name), ?\s, column_type(type, opts), column_options(opts)]
1203+
["ADD ", quote_name(name), ?\s, column_type(type, opts), column_options(type, opts)]
12041204
end
12051205

12061206
defp column_change(table, {:add_if_not_exists, name, %Reference{} = ref, opts}) do
@@ -1209,13 +1209,19 @@ if Code.ensure_loaded?(MyXQL) do
12091209
quote_name(name),
12101210
?\s,
12111211
reference_column_type(ref.type, opts),
1212-
column_options(opts),
1212+
column_options(ref.type, opts),
12131213
constraint_if_not_exists_expr(ref, table, name)
12141214
]
12151215
end
12161216

12171217
defp column_change(_table, {:add_if_not_exists, name, type, opts}) do
1218-
["ADD IF NOT EXISTS ", quote_name(name), ?\s, column_type(type, opts), column_options(opts)]
1218+
[
1219+
"ADD IF NOT EXISTS ",
1220+
quote_name(name),
1221+
?\s,
1222+
column_type(type, opts),
1223+
column_options(type, opts)
1224+
]
12191225
end
12201226

12211227
defp column_change(table, {:modify, name, %Reference{} = ref, opts}) do
@@ -1225,7 +1231,7 @@ if Code.ensure_loaded?(MyXQL) do
12251231
quote_name(name),
12261232
?\s,
12271233
reference_column_type(ref.type, opts),
1228-
column_options(opts),
1234+
column_options(ref.type, opts),
12291235
constraint_expr(ref, table, name)
12301236
]
12311237
end
@@ -1237,7 +1243,7 @@ if Code.ensure_loaded?(MyXQL) do
12371243
quote_name(name),
12381244
?\s,
12391245
column_type(type, opts),
1240-
column_options(opts)
1246+
column_options(type, opts)
12411247
]
12421248
end
12431249

@@ -1259,13 +1265,20 @@ if Code.ensure_loaded?(MyXQL) do
12591265
defp column_change(_table, {:remove_if_exists, name}),
12601266
do: ["DROP IF EXISTS ", quote_name(name)]
12611267

1262-
defp column_options(opts) do
1268+
defp column_options(type, opts) do
12631269
default = Keyword.fetch(opts, :default)
12641270
null = Keyword.get(opts, :null)
12651271
after_column = Keyword.get(opts, :after)
12661272
comment = Keyword.get(opts, :comment)
1273+
collation = Keyword.fetch(opts, :collation)
12671274

1268-
[default_expr(default), null_expr(null), comment_expr(comment), after_expr(after_column)]
1275+
[
1276+
default_expr(default),
1277+
collation(collation, type),
1278+
null_expr(null),
1279+
comment_expr(comment),
1280+
after_expr(after_column)
1281+
]
12691282
end
12701283

12711284
defp comment_expr(comment, create_table? \\ false)
@@ -1286,6 +1299,13 @@ if Code.ensure_loaded?(MyXQL) do
12861299
defp null_expr(true), do: " NULL"
12871300
defp null_expr(_), do: []
12881301

1302+
defp collation({:ok, collation_name}, text_type)
1303+
when text_type in ~w/string char varchar text tinytext mediumtext longtext/a do
1304+
" COLLATE \"#{collation_name}\""
1305+
end
1306+
1307+
defp collation(_, _), do: []
1308+
12891309
defp new_constraint_expr(%Constraint{check: check} = constraint) when is_binary(check) do
12901310
[
12911311
"CONSTRAINT ",

0 commit comments

Comments
 (0)