type.exs (21228B)
1 defmodule Ecto.Integration.TypeTest do 2 use Ecto.Integration.Case, async: Application.compile_env(:ecto, :async_integration_tests, true) 3 4 alias Ecto.Integration.{Comment, Custom, Item, ItemColor, Order, Post, User, Tag, Usec} 5 alias Ecto.Integration.TestRepo 6 import Ecto.Query 7 8 @parameterized_type Ecto.ParameterizedType.init(Ecto.Enum, values: [:a, :b]) 9 10 test "primitive types" do 11 integer = 1 12 float = 0.1 13 blob = <<0, 1>> 14 uuid = "00010203-0405-4607-8809-0a0b0c0d0e0f" 15 datetime = ~N[2014-01-16 20:26:51] 16 17 TestRepo.insert!(%Post{blob: blob, public: true, visits: integer, uuid: uuid, 18 counter: integer, inserted_at: datetime, intensity: float}) 19 20 # nil 21 assert [nil] = TestRepo.all(from Post, select: nil) 22 23 # ID 24 assert [1] = TestRepo.all(from p in Post, where: p.counter == ^integer, select: p.counter) 25 26 # Integers 27 assert [1] = TestRepo.all(from p in Post, where: p.visits == ^integer, select: p.visits) 28 assert [1] = TestRepo.all(from p in Post, where: p.visits == 1, select: p.visits) 29 assert [3] = TestRepo.all(from p in Post, select: p.visits + 2) 30 31 # Floats 32 assert [0.1] = TestRepo.all(from p in Post, where: p.intensity == ^float, select: p.intensity) 33 assert [0.1] = TestRepo.all(from p in Post, where: p.intensity == 0.1, select: p.intensity) 34 assert [1500.0] = TestRepo.all(from p in Post, select: 1500.0) 35 assert [0.5] = TestRepo.all(from p in Post, select: p.intensity * 5) 36 37 # Booleans 38 assert [true] = TestRepo.all(from p in Post, where: p.public == ^true, select: p.public) 39 assert [true] = TestRepo.all(from p in Post, where: p.public == true, select: p.public) 40 41 # Binaries 42 assert [^blob] = TestRepo.all(from p in Post, where: p.blob == <<0, 1>>, select: p.blob) 43 assert [^blob] = TestRepo.all(from p in Post, where: p.blob == ^blob, select: p.blob) 44 45 # UUID 46 assert [^uuid] = TestRepo.all(from p in Post, where: p.uuid == ^uuid, select: p.uuid) 47 48 # NaiveDatetime 49 assert [^datetime] = TestRepo.all(from p in Post, where: p.inserted_at == ^datetime, select: p.inserted_at) 50 51 # Datetime 52 datetime = DateTime.from_unix!(System.os_time(:second), :second) 53 TestRepo.insert!(%User{inserted_at: datetime}) 54 assert [^datetime] = TestRepo.all(from u in User, where: u.inserted_at == ^datetime, select: u.inserted_at) 55 56 # usec 57 naive_datetime = ~N[2014-01-16 20:26:51.000000] 58 datetime = DateTime.from_naive!(~N[2014-01-16 20:26:51.000000], "Etc/UTC") 59 TestRepo.insert!(%Usec{naive_datetime_usec: naive_datetime, utc_datetime_usec: datetime}) 60 assert [^naive_datetime] = TestRepo.all(from u in Usec, where: u.naive_datetime_usec == ^naive_datetime, select: u.naive_datetime_usec) 61 assert [^datetime] = TestRepo.all(from u in Usec, where: u.utc_datetime_usec == ^datetime, select: u.utc_datetime_usec) 62 63 naive_datetime = ~N[2014-01-16 20:26:51.123000] 64 datetime = DateTime.from_naive!(~N[2014-01-16 20:26:51.123000], "Etc/UTC") 65 TestRepo.insert!(%Usec{naive_datetime_usec: naive_datetime, utc_datetime_usec: datetime}) 66 assert [^naive_datetime] = TestRepo.all(from u in Usec, where: u.naive_datetime_usec == ^naive_datetime, select: u.naive_datetime_usec) 67 assert [^datetime] = TestRepo.all(from u in Usec, where: u.utc_datetime_usec == ^datetime, select: u.utc_datetime_usec) 68 end 69 70 @tag :select_not 71 test "primitive types boolean negate" do 72 TestRepo.insert!(%Post{public: true}) 73 assert [false] = TestRepo.all(from p in Post, where: p.public == true, select: not p.public) 74 assert [true] = TestRepo.all(from p in Post, where: p.public == true, select: not not p.public) 75 end 76 77 test "aggregate types" do 78 datetime = ~N[2014-01-16 20:26:51] 79 TestRepo.insert!(%Post{inserted_at: datetime}) 80 query = from p in Post, select: max(p.inserted_at) 81 assert [^datetime] = TestRepo.all(query) 82 end 83 84 # We don't specifically assert on the tuple content because 85 # some databases would return integer, others decimal. 86 # The important is that the type has been invoked for wrapping. 87 test "aggregate custom types" do 88 TestRepo.insert!(%Post{wrapped_visits: {:int, 10}}) 89 query = from p in Post, select: sum(p.wrapped_visits) 90 assert [{:int, _}] = TestRepo.all(query) 91 end 92 93 @tag :aggregate_filters 94 test "aggregate filter types" do 95 datetime = ~N[2014-01-16 20:26:51] 96 TestRepo.insert!(%Post{inserted_at: datetime}) 97 query = from p in Post, select: filter(max(p.inserted_at), p.public == ^true) 98 assert [^datetime] = TestRepo.all(query) 99 end 100 101 test "coalesce text type when default" do 102 TestRepo.insert!(%Post{blob: nil}) 103 blob = <<0, 1>> 104 query = from p in Post, select: coalesce(p.blob, ^blob) 105 assert [^blob] = TestRepo.all(query) 106 end 107 108 test "coalesce text type when value" do 109 blob = <<0, 2>> 110 default_blob = <<0, 1>> 111 TestRepo.insert!(%Post{blob: blob}) 112 query = from p in Post, select: coalesce(p.blob, ^default_blob) 113 assert [^blob] = TestRepo.all(query) 114 end 115 116 test "tagged types" do 117 %{id: post_id} = TestRepo.insert!(%Post{visits: 12}) 118 TestRepo.insert!(%Comment{text: "#{post_id}", post_id: post_id}) 119 120 # Numbers 121 assert [1] = TestRepo.all(from Post, select: type(^"1", :integer)) 122 assert [1.0] = TestRepo.all(from Post, select: type(^1.0, :float)) 123 assert [1] = TestRepo.all(from p in Post, select: type(^"1", p.visits)) 124 assert [1.0] = TestRepo.all(from p in Post, select: type(^"1", p.intensity)) 125 126 # Custom wrappers 127 assert [1] = TestRepo.all(from Post, select: type(^"1", CustomPermalink)) 128 129 # Custom types 130 uuid = Ecto.UUID.generate() 131 assert [^uuid] = TestRepo.all(from Post, select: type(^uuid, Ecto.UUID)) 132 133 # Parameterized types 134 assert [:a] = TestRepo.all(from Post, select: type(^"a", ^@parameterized_type)) 135 136 # Math operations 137 assert [4] = TestRepo.all(from Post, select: type(2 + ^"2", :integer)) 138 assert [4.0] = TestRepo.all(from Post, select: type(2.0 + ^"2", :float)) 139 assert [4] = TestRepo.all(from p in Post, select: type(2 + ^"2", p.visits)) 140 assert [4.0] = TestRepo.all(from p in Post, select: type(2.0 + ^"2", p.intensity)) 141 142 # Comparison expression 143 assert [12] = TestRepo.all(from p in Post, select: type(coalesce(p.visits, 0), :integer)) 144 assert [1.0] = TestRepo.all(from p in Post, select: type(coalesce(p.intensity, 1.0), :float)) 145 146 # parent_as/1 147 child = from c in Comment, where: type(parent_as(:posts).id, :string) == c.text, select: c.post_id 148 query = from p in Post, as: :posts, where: p.id in subquery(child), select: p.id 149 assert [post_id] == TestRepo.all(query) 150 end 151 152 test "binary id type" do 153 assert %Custom{} = custom = TestRepo.insert!(%Custom{}) 154 bid = custom.bid 155 assert [^bid] = TestRepo.all(from c in Custom, select: c.bid) 156 assert [^bid] = TestRepo.all(from c in Custom, select: type(^bid, :binary_id)) 157 end 158 159 @tag :like_match_blob 160 test "text type as blob" do 161 assert %Post{} = post = TestRepo.insert!(%Post{blob: <<0, 1, 2>>}) 162 id = post.id 163 assert post.blob == <<0, 1, 2>> 164 assert [^id] = TestRepo.all(from p in Post, where: like(p.blob, ^<<0, 1, 2>>), select: p.id) 165 end 166 167 @tag :like_match_blob 168 @tag :text_type_as_string 169 test "text type as string" do 170 assert %Post{} = post = TestRepo.insert!(%Post{blob: "hello"}) 171 id = post.id 172 assert post.blob == "hello" 173 assert [^id] = TestRepo.all(from p in Post, where: like(p.blob, ^"hello"), select: p.id) 174 end 175 176 @tag :array_type 177 test "array type" do 178 ints = [1, 2, 3] 179 tag = TestRepo.insert!(%Tag{ints: ints}) 180 181 assert TestRepo.all(from t in Tag, where: t.ints == ^[], select: t.ints) == [] 182 assert TestRepo.all(from t in Tag, where: t.ints == ^[1, 2, 3], select: t.ints) == [ints] 183 184 # Both sides interpolation 185 assert TestRepo.all(from t in Tag, where: ^"b" in ^["a", "b", "c"], select: t.ints) == [ints] 186 assert TestRepo.all(from t in Tag, where: ^"b" in [^"a", ^"b", ^"c"], select: t.ints) == [ints] 187 188 # Querying 189 assert TestRepo.all(from t in Tag, where: t.ints == [1, 2, 3], select: t.ints) == [ints] 190 assert TestRepo.all(from t in Tag, where: 0 in t.ints, select: t.ints) == [] 191 assert TestRepo.all(from t in Tag, where: 1 in t.ints, select: t.ints) == [ints] 192 193 # Update 194 tag = TestRepo.update!(Ecto.Changeset.change tag, ints: nil) 195 assert TestRepo.get!(Tag, tag.id).ints == nil 196 197 tag = TestRepo.update!(Ecto.Changeset.change tag, ints: [3, 2, 1]) 198 assert TestRepo.get!(Tag, tag.id).ints == [3, 2, 1] 199 200 # Update all 201 {1, _} = TestRepo.update_all(Tag, push: [ints: 0]) 202 assert TestRepo.get!(Tag, tag.id).ints == [3, 2, 1, 0] 203 204 {1, _} = TestRepo.update_all(Tag, pull: [ints: 2]) 205 assert TestRepo.get!(Tag, tag.id).ints == [3, 1, 0] 206 207 {1, _} = TestRepo.update_all(Tag, set: [ints: nil]) 208 assert TestRepo.get!(Tag, tag.id).ints == nil 209 end 210 211 @tag :array_type 212 test "array type with custom types" do 213 uuids = ["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"] 214 TestRepo.insert!(%Tag{uuids: ["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"]}) 215 216 assert TestRepo.all(from t in Tag, where: t.uuids == ^[], select: t.uuids) == [] 217 assert TestRepo.all(from t in Tag, where: t.uuids == ^["51fcfbdd-ad60-4ccb-8bf9-47aabd66d075"], 218 select: t.uuids) == [uuids] 219 220 {1, _} = TestRepo.update_all(Tag, set: [uuids: nil]) 221 assert TestRepo.all(from t in Tag, select: t.uuids) == [nil] 222 end 223 224 @tag :array_type 225 test "array type with nil in array" do 226 tag = TestRepo.insert!(%Tag{ints: [1, nil, 3]}) 227 assert tag.ints == [1, nil, 3] 228 end 229 230 @tag :map_type 231 test "untyped map" do 232 post1 = TestRepo.insert!(%Post{meta: %{"foo" => "bar", "baz" => "bat"}}) 233 post2 = TestRepo.insert!(%Post{meta: %{foo: "bar", baz: "bat"}}) 234 235 assert TestRepo.all(from p in Post, where: p.id == ^post1.id, select: p.meta) == 236 [%{"foo" => "bar", "baz" => "bat"}] 237 assert TestRepo.all(from p in Post, where: p.id == ^post2.id, select: p.meta) == 238 [%{"foo" => "bar", "baz" => "bat"}] 239 end 240 241 @tag :map_type 242 test "typed string map" do 243 post1 = TestRepo.insert!(%Post{links: %{"foo" => "http://foo.com", "bar" => "http://bar.com"}}) 244 post2 = TestRepo.insert!(%Post{links: %{foo: "http://foo.com", bar: "http://bar.com"}}) 245 246 assert TestRepo.all(from p in Post, where: p.id == ^post1.id, select: p.links) == 247 [%{"foo" => "http://foo.com", "bar" => "http://bar.com"}] 248 assert TestRepo.all(from p in Post, where: p.id == ^post2.id, select: p.links) == 249 [%{"foo" => "http://foo.com", "bar" => "http://bar.com"}] 250 end 251 252 @tag :map_type 253 test "typed float map" do 254 post = TestRepo.insert!(%Post{intensities: %{"foo" => 1.0, "bar" => 416500.0}}) 255 256 # Note we are using === since we want to check integer vs float 257 assert TestRepo.all(from p in Post, where: p.id == ^post.id, select: p.intensities) === 258 [%{"foo" => 1.0, "bar" => 416500.0}] 259 end 260 261 @tag :map_type 262 test "map type on update" do 263 post = TestRepo.insert!(%Post{meta: %{"world" => "hello"}}) 264 assert TestRepo.get!(Post, post.id).meta == %{"world" => "hello"} 265 266 post = TestRepo.update!(Ecto.Changeset.change post, meta: %{hello: "world"}) 267 assert TestRepo.get!(Post, post.id).meta == %{"hello" => "world"} 268 269 query = from(p in Post, where: p.id == ^post.id) 270 TestRepo.update_all(query, set: [meta: %{world: "hello"}]) 271 assert TestRepo.get!(Post, post.id).meta == %{"world" => "hello"} 272 end 273 274 @tag :map_type 275 test "embeds one" do 276 item = %Item{price: 123, valid_at: ~D[2014-01-16]} 277 278 order = 279 %Order{} 280 |> Ecto.Changeset.change 281 |> Ecto.Changeset.put_embed(:item, item) 282 |> TestRepo.insert!() 283 284 dbitem = TestRepo.get!(Order, order.id).item 285 assert item.reference == dbitem.reference 286 assert item.price == dbitem.price 287 assert item.valid_at == dbitem.valid_at 288 assert dbitem.id 289 290 [dbitem] = TestRepo.all(from o in Order, select: o.item) 291 assert item.reference == dbitem.reference 292 assert item.price == dbitem.price 293 assert item.valid_at == dbitem.valid_at 294 assert dbitem.id 295 296 {1, _} = TestRepo.update_all(Order, set: [item: %{dbitem | price: 456}]) 297 assert TestRepo.get!(Order, order.id).item.price == 456 298 end 299 300 @tag :map_type 301 @tag :json_extract_path 302 test "json_extract_path with primitive values" do 303 order = %Order{metadata: 304 %{ 305 :id => 123, 306 :time => ~T[09:00:00], 307 "code" => "good", 308 "'single quoted'" => "bar", 309 "\"double quoted\"" => "baz", 310 "enabled" => true, 311 "extra" => [%{"enabled" => false}] 312 } 313 } 314 315 order = TestRepo.insert!(order) 316 317 assert TestRepo.one(from o in Order, select: o.metadata["id"]) == 123 318 assert TestRepo.one(from o in Order, select: o.metadata["bad"]) == nil 319 assert TestRepo.one(from o in Order, select: o.metadata["bad"]["bad"]) == nil 320 321 field = "id" 322 assert TestRepo.one(from o in Order, select: o.metadata[^field]) == 123 323 assert TestRepo.one(from o in Order, select: o.metadata["time"]) == "09:00:00" 324 assert TestRepo.one(from o in Order, select: o.metadata["'single quoted'"]) == "bar" 325 assert TestRepo.one(from o in Order, select: o.metadata["';"]) == nil 326 assert TestRepo.one(from o in Order, select: o.metadata["\"double quoted\""]) == "baz" 327 assert TestRepo.one(from o in Order, select: o.metadata["enabled"]) == true 328 assert TestRepo.one(from o in Order, select: o.metadata["extra"][0]["enabled"]) == false 329 330 # where 331 assert TestRepo.one(from o in Order, where: o.metadata["id"] == 123, select: o.id) == order.id 332 assert TestRepo.one(from o in Order, where: o.metadata["id"] == 456, select: o.id) == nil 333 assert TestRepo.one(from o in Order, where: o.metadata["code"] == "good", select: o.id) == order.id 334 assert TestRepo.one(from o in Order, where: o.metadata["code"] == "bad", select: o.id) == nil 335 assert TestRepo.one(from o in Order, where: o.metadata["enabled"] == true, select: o.id) == order.id 336 assert TestRepo.one(from o in Order, where: o.metadata["extra"][0]["enabled"] == false, select: o.id) == order.id 337 end 338 339 @tag :map_type 340 @tag :json_extract_path 341 test "json_extract_path with arrays and objects" do 342 order = %Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}} 343 order = TestRepo.insert!(order) 344 345 assert TestRepo.one(from o in Order, select: o.metadata["tags"][0]["name"]) == "red" 346 assert TestRepo.one(from o in Order, select: o.metadata["tags"][99]["name"]) == nil 347 348 index = 1 349 assert TestRepo.one(from o in Order, select: o.metadata["tags"][^index]["name"]) == "green" 350 351 # where 352 assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id) == order.id 353 assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "blue", select: o.id) == nil 354 assert TestRepo.one(from o in Order, where: o.metadata["tags"][99]["name"] == "red", select: o.id) == nil 355 end 356 357 @tag :map_type 358 @tag :json_extract_path 359 test "json_extract_path with embeds" do 360 order = %Order{items: [%{valid_at: ~D[2020-01-01]}]} 361 TestRepo.insert!(order) 362 363 assert TestRepo.one(from o in Order, select: o.items[0]["valid_at"]) == "2020-01-01" 364 end 365 366 @tag :map_type 367 @tag :json_extract_path 368 test "json_extract_path with custom field source" do 369 order = TestRepo.insert!(%Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}}) 370 371 assert TestRepo.one(from o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id) == order.id 372 end 373 374 @tag :map_type 375 @tag :map_type_schemaless 376 test "embeds one with custom type" do 377 item = %Item{price: 123, reference: "PREFIX-EXAMPLE"} 378 379 order = 380 %Order{} 381 |> Ecto.Changeset.change 382 |> Ecto.Changeset.put_embed(:item, item) 383 |> TestRepo.insert!() 384 385 dbitem = TestRepo.get!(Order, order.id).item 386 assert dbitem.reference == "PREFIX-EXAMPLE" 387 assert [%{"reference" => "EXAMPLE"}] = TestRepo.all(from o in "orders", select: o.item) 388 end 389 390 @tag :map_type 391 test "empty embeds one" do 392 order = TestRepo.insert!(%Order{}) 393 assert order.item == nil 394 assert TestRepo.get!(Order, order.id).item == nil 395 end 396 397 @tag :map_type 398 @tag :array_type 399 test "embeds many" do 400 item = %Item{price: 123, valid_at: ~D[2014-01-16]} 401 tag = 402 %Tag{} 403 |> Ecto.Changeset.change 404 |> Ecto.Changeset.put_embed(:items, [item]) 405 tag = TestRepo.insert!(tag) 406 407 [dbitem] = TestRepo.get!(Tag, tag.id).items 408 assert item.price == dbitem.price 409 assert item.valid_at == dbitem.valid_at 410 assert dbitem.id 411 412 [[dbitem]] = TestRepo.all(from t in Tag, select: t.items) 413 assert item.price == dbitem.price 414 assert item.valid_at == dbitem.valid_at 415 assert dbitem.id 416 417 {1, _} = TestRepo.update_all(Tag, set: [items: [%{dbitem | price: 456}]]) 418 assert (TestRepo.get!(Tag, tag.id).items |> hd).price == 456 419 end 420 421 @tag :map_type 422 @tag :array_type 423 test "empty embeds many" do 424 tag = TestRepo.insert!(%Tag{}) 425 assert tag.items == [] 426 assert TestRepo.get!(Tag, tag.id).items == [] 427 end 428 429 @tag :map_type 430 @tag :array_type 431 test "nested embeds" do 432 red = %ItemColor{name: "red"} 433 blue = %ItemColor{name: "blue"} 434 item = %Item{ 435 primary_color: red, 436 secondary_colors: [blue] 437 } 438 439 order = 440 %Order{} 441 |> Ecto.Changeset.change 442 |> Ecto.Changeset.put_embed(:item, item) 443 order = TestRepo.insert!(order) 444 445 dbitem = TestRepo.get!(Order, order.id).item 446 assert dbitem.primary_color.name == "red" 447 assert Enum.map(dbitem.secondary_colors, & &1.name) == ["blue"] 448 assert dbitem.id 449 assert dbitem.primary_color.id 450 451 [dbitem] = TestRepo.all(from o in Order, select: o.item) 452 assert dbitem.primary_color.name == "red" 453 assert Enum.map(dbitem.secondary_colors, & &1.name) == ["blue"] 454 assert dbitem.id 455 assert dbitem.primary_color.id 456 end 457 458 @tag :decimal_type 459 test "decimal type" do 460 decimal = Decimal.new("1.0") 461 TestRepo.insert!(%Post{cost: decimal}) 462 463 [cost] = TestRepo.all(from p in Post, where: p.cost == ^decimal, select: p.cost) 464 assert Decimal.equal?(decimal, cost) 465 [cost] = TestRepo.all(from p in Post, where: p.cost == ^1.0, select: p.cost) 466 assert Decimal.equal?(decimal, cost) 467 [cost] = TestRepo.all(from p in Post, where: p.cost == ^1, select: p.cost) 468 assert Decimal.equal?(decimal, cost) 469 [cost] = TestRepo.all(from p in Post, where: p.cost == 1.0, select: p.cost) 470 assert Decimal.equal?(decimal, cost) 471 [cost] = TestRepo.all(from p in Post, where: p.cost == 1, select: p.cost) 472 assert Decimal.equal?(decimal, cost) 473 [cost] = TestRepo.all(from p in Post, select: p.cost * 2) 474 assert Decimal.equal?(Decimal.new("2.0"), cost) 475 [cost] = TestRepo.all(from p in Post, select: p.cost - p.cost) 476 assert Decimal.equal?(Decimal.new("0.0"), cost) 477 end 478 479 @tag :decimal_type 480 @tag :decimal_precision 481 test "decimal typed aggregations" do 482 decimal = Decimal.new("1.0") 483 TestRepo.insert!(%Post{cost: decimal}) 484 485 assert [1] = TestRepo.all(from p in Post, select: type(sum(p.cost), :integer)) 486 assert [1.0] = TestRepo.all(from p in Post, select: type(sum(p.cost), :float)) 487 [cost] = TestRepo.all(from p in Post, select: type(sum(p.cost), :decimal)) 488 assert Decimal.equal?(decimal, cost) 489 end 490 491 @tag :decimal_type 492 test "on coalesce with mixed types" do 493 decimal = Decimal.new("1.0") 494 TestRepo.insert!(%Post{cost: decimal}) 495 [cost] = TestRepo.all(from p in Post, select: coalesce(p.cost, 0)) 496 assert Decimal.equal?(decimal, cost) 497 end 498 499 @tag :union_with_literals 500 test "unions with literals" do 501 TestRepo.insert!(%Post{}) 502 TestRepo.insert!(%Post{}) 503 504 query1 = from(p in Post, select: %{n: 1}) 505 query2 = from(p in Post, select: %{n: 2}) 506 507 assert TestRepo.all(union_all(query1, ^query2)) == 508 [%{n: 1}, %{n: 1}, %{n: 2}, %{n: 2}] 509 510 query1 = from(p in Post, select: %{n: 1.0}) 511 query2 = from(p in Post, select: %{n: 2.0}) 512 513 assert TestRepo.all(union_all(query1, ^query2)) == 514 [%{n: 1.0}, %{n: 1.0}, %{n: 2.0}, %{n: 2.0}] 515 516 query1 = from(p in Post, select: %{n: "foo"}) 517 query2 = from(p in Post, select: %{n: "bar"}) 518 519 assert TestRepo.all(union_all(query1, ^query2)) == 520 [%{n: "foo"}, %{n: "foo"}, %{n: "bar"}, %{n: "bar"}] 521 end 522 523 test "schemaless types" do 524 TestRepo.insert!(%Post{visits: 123}) 525 assert [123] = TestRepo.all(from p in "posts", select: type(p.visits, :integer)) 526 end 527 528 test "schemaless calendar types" do 529 datetime = ~N[2014-01-16 20:26:51] 530 assert {1, _} = 531 TestRepo.insert_all("posts", [[inserted_at: datetime]]) 532 assert {1, _} = 533 TestRepo.update_all("posts", set: [inserted_at: datetime]) 534 assert [_] = 535 TestRepo.all(from p in "posts", where: p.inserted_at >= ^datetime, select: p.inserted_at) 536 assert [_] = 537 TestRepo.all(from p in "posts", where: p.inserted_at in [^datetime], select: p.inserted_at) 538 assert [_] = 539 TestRepo.all(from p in "posts", where: p.inserted_at in ^[datetime], select: p.inserted_at) 540 end 541 end