Skip to content

Commit db2d60d

Browse files
committedJun 18, 2025·
test: add tests for new boolean expressions
·
v2.6.11v2.6.8
1 parent 46f325e commit db2d60d

File tree

4 files changed

+745
-0
lines changed

4 files changed

+745
-0
lines changed
 
Lines changed: 690 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,690 @@
1+
{
2+
"attributes": [
3+
{
4+
"allow_nil?": false,
5+
"default": "fragment(\"gen_random_uuid()\")",
6+
"generated?": false,
7+
"precision": null,
8+
"primary_key?": true,
9+
"references": null,
10+
"scale": null,
11+
"size": null,
12+
"source": "id",
13+
"type": "uuid"
14+
},
15+
{
16+
"allow_nil?": false,
17+
"default": "1",
18+
"generated?": false,
19+
"precision": null,
20+
"primary_key?": false,
21+
"references": null,
22+
"scale": null,
23+
"size": null,
24+
"source": "version",
25+
"type": "bigint"
26+
},
27+
{
28+
"allow_nil?": true,
29+
"default": "nil",
30+
"generated?": false,
31+
"precision": null,
32+
"primary_key?": false,
33+
"references": null,
34+
"scale": null,
35+
"size": null,
36+
"source": "title_column",
37+
"type": "text"
38+
},
39+
{
40+
"allow_nil?": true,
41+
"default": "nil",
42+
"generated?": false,
43+
"precision": null,
44+
"primary_key?": false,
45+
"references": null,
46+
"scale": null,
47+
"size": null,
48+
"source": "not_selected_by_default",
49+
"type": "text"
50+
},
51+
{
52+
"allow_nil?": true,
53+
"default": "nil",
54+
"generated?": false,
55+
"precision": null,
56+
"primary_key?": false,
57+
"references": null,
58+
"scale": null,
59+
"size": null,
60+
"source": "datetime",
61+
"type": "timestamptz(6)"
62+
},
63+
{
64+
"allow_nil?": true,
65+
"default": "nil",
66+
"generated?": false,
67+
"precision": null,
68+
"primary_key?": false,
69+
"references": null,
70+
"scale": null,
71+
"size": null,
72+
"source": "score",
73+
"type": "bigint"
74+
},
75+
{
76+
"allow_nil?": true,
77+
"default": "nil",
78+
"generated?": false,
79+
"precision": null,
80+
"primary_key?": false,
81+
"references": null,
82+
"scale": null,
83+
"size": null,
84+
"source": "limited_score",
85+
"type": "bigint"
86+
},
87+
{
88+
"allow_nil?": true,
89+
"default": "nil",
90+
"generated?": false,
91+
"precision": null,
92+
"primary_key?": false,
93+
"references": null,
94+
"scale": null,
95+
"size": null,
96+
"source": "public",
97+
"type": "boolean"
98+
},
99+
{
100+
"allow_nil?": false,
101+
"default": "true",
102+
"generated?": false,
103+
"precision": null,
104+
"primary_key?": false,
105+
"references": null,
106+
"scale": null,
107+
"size": null,
108+
"source": "is_special",
109+
"type": "boolean"
110+
},
111+
{
112+
"allow_nil?": true,
113+
"default": "nil",
114+
"generated?": false,
115+
"precision": null,
116+
"primary_key?": false,
117+
"references": null,
118+
"scale": null,
119+
"size": null,
120+
"source": "category",
121+
"type": "citext"
122+
},
123+
{
124+
"allow_nil?": true,
125+
"default": "\"sponsored\"",
126+
"generated?": false,
127+
"precision": null,
128+
"primary_key?": false,
129+
"references": null,
130+
"scale": null,
131+
"size": null,
132+
"source": "type",
133+
"type": "text"
134+
},
135+
{
136+
"allow_nil?": true,
137+
"default": "nil",
138+
"generated?": false,
139+
"precision": null,
140+
"primary_key?": false,
141+
"references": null,
142+
"scale": null,
143+
"size": null,
144+
"source": "price",
145+
"type": "bigint"
146+
},
147+
{
148+
"allow_nil?": true,
149+
"default": "\"0\"",
150+
"generated?": false,
151+
"precision": null,
152+
"primary_key?": false,
153+
"references": null,
154+
"scale": null,
155+
"size": null,
156+
"source": "decimal",
157+
"type": "decimal"
158+
},
159+
{
160+
"allow_nil?": true,
161+
"default": "nil",
162+
"generated?": false,
163+
"precision": null,
164+
"primary_key?": false,
165+
"references": null,
166+
"scale": null,
167+
"size": null,
168+
"source": "status",
169+
"type": "text"
170+
},
171+
{
172+
"allow_nil?": true,
173+
"default": "nil",
174+
"generated?": false,
175+
"precision": null,
176+
"primary_key?": false,
177+
"references": null,
178+
"scale": null,
179+
"size": null,
180+
"source": "status_enum",
181+
"type": "status"
182+
},
183+
{
184+
"allow_nil?": true,
185+
"default": "nil",
186+
"generated?": false,
187+
"precision": null,
188+
"primary_key?": false,
189+
"references": null,
190+
"scale": null,
191+
"size": null,
192+
"source": "metadata",
193+
"type": "map"
194+
},
195+
{
196+
"allow_nil?": false,
197+
"default": "2",
198+
"generated?": false,
199+
"precision": null,
200+
"primary_key?": false,
201+
"references": null,
202+
"scale": null,
203+
"size": null,
204+
"source": "constrained_int",
205+
"type": "bigint"
206+
},
207+
{
208+
"allow_nil?": true,
209+
"default": "nil",
210+
"generated?": false,
211+
"precision": null,
212+
"primary_key?": false,
213+
"references": null,
214+
"scale": null,
215+
"size": null,
216+
"source": "point",
217+
"type": [
218+
"array",
219+
"float"
220+
]
221+
},
222+
{
223+
"allow_nil?": true,
224+
"default": "nil",
225+
"generated?": false,
226+
"precision": null,
227+
"primary_key?": false,
228+
"references": null,
229+
"scale": null,
230+
"size": null,
231+
"source": "composite_point",
232+
"type": "custom_point"
233+
},
234+
{
235+
"allow_nil?": true,
236+
"default": "nil",
237+
"generated?": false,
238+
"precision": null,
239+
"primary_key?": false,
240+
"references": null,
241+
"scale": null,
242+
"size": null,
243+
"source": "string_point",
244+
"type": "text"
245+
},
246+
{
247+
"allow_nil?": true,
248+
"default": "nil",
249+
"generated?": false,
250+
"precision": null,
251+
"primary_key?": false,
252+
"references": null,
253+
"scale": null,
254+
"size": null,
255+
"source": "person_detail",
256+
"type": "map"
257+
},
258+
{
259+
"allow_nil?": true,
260+
"default": "nil",
261+
"generated?": false,
262+
"precision": null,
263+
"primary_key?": false,
264+
"references": null,
265+
"scale": null,
266+
"size": null,
267+
"source": "stuff",
268+
"type": "map"
269+
},
270+
{
271+
"allow_nil?": true,
272+
"default": "nil",
273+
"generated?": false,
274+
"precision": null,
275+
"primary_key?": false,
276+
"references": null,
277+
"scale": null,
278+
"size": null,
279+
"source": "list_of_stuff",
280+
"type": [
281+
"array",
282+
"map"
283+
]
284+
},
285+
{
286+
"allow_nil?": true,
287+
"default": "nil",
288+
"generated?": false,
289+
"precision": null,
290+
"primary_key?": false,
291+
"references": null,
292+
"scale": null,
293+
"size": null,
294+
"source": "uniq_one",
295+
"type": "text"
296+
},
297+
{
298+
"allow_nil?": true,
299+
"default": "nil",
300+
"generated?": false,
301+
"precision": null,
302+
"primary_key?": false,
303+
"references": null,
304+
"scale": null,
305+
"size": null,
306+
"source": "uniq_two",
307+
"type": "text"
308+
},
309+
{
310+
"allow_nil?": true,
311+
"default": "nil",
312+
"generated?": false,
313+
"precision": null,
314+
"primary_key?": false,
315+
"references": null,
316+
"scale": null,
317+
"size": null,
318+
"source": "uniq_custom_one",
319+
"type": "text"
320+
},
321+
{
322+
"allow_nil?": true,
323+
"default": "nil",
324+
"generated?": false,
325+
"precision": null,
326+
"primary_key?": false,
327+
"references": null,
328+
"scale": null,
329+
"size": null,
330+
"source": "uniq_custom_two",
331+
"type": "text"
332+
},
333+
{
334+
"allow_nil?": true,
335+
"default": "nil",
336+
"generated?": false,
337+
"precision": null,
338+
"primary_key?": false,
339+
"references": null,
340+
"scale": null,
341+
"size": null,
342+
"source": "uniq_on_upper",
343+
"type": "text"
344+
},
345+
{
346+
"allow_nil?": true,
347+
"default": "nil",
348+
"generated?": false,
349+
"precision": null,
350+
"primary_key?": false,
351+
"references": null,
352+
"scale": null,
353+
"size": null,
354+
"source": "uniq_if_contains_foo",
355+
"type": "text"
356+
},
357+
{
358+
"allow_nil?": true,
359+
"default": "nil",
360+
"generated?": false,
361+
"precision": null,
362+
"primary_key?": false,
363+
"references": null,
364+
"scale": null,
365+
"size": null,
366+
"source": "model",
367+
"type": "map"
368+
},
369+
{
370+
"allow_nil?": true,
371+
"default": "nil",
372+
"generated?": false,
373+
"precision": null,
374+
"primary_key?": false,
375+
"references": null,
376+
"scale": null,
377+
"size": null,
378+
"source": "list_containing_nils",
379+
"type": [
380+
"array",
381+
"text"
382+
]
383+
},
384+
{
385+
"allow_nil?": true,
386+
"default": "nil",
387+
"generated?": false,
388+
"precision": null,
389+
"primary_key?": false,
390+
"references": null,
391+
"scale": null,
392+
"size": null,
393+
"source": "ltree_unescaped",
394+
"type": "ltree"
395+
},
396+
{
397+
"allow_nil?": true,
398+
"default": "nil",
399+
"generated?": false,
400+
"precision": null,
401+
"primary_key?": false,
402+
"references": null,
403+
"scale": null,
404+
"size": null,
405+
"source": "ltree_escaped",
406+
"type": "ltree"
407+
},
408+
{
409+
"allow_nil?": false,
410+
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
411+
"generated?": false,
412+
"precision": null,
413+
"primary_key?": false,
414+
"references": null,
415+
"scale": null,
416+
"size": null,
417+
"source": "created_at",
418+
"type": "utc_datetime_usec"
419+
},
420+
{
421+
"allow_nil?": false,
422+
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
423+
"generated?": false,
424+
"precision": null,
425+
"primary_key?": false,
426+
"references": null,
427+
"scale": null,
428+
"size": null,
429+
"source": "updated_at",
430+
"type": "timestamptz(6)"
431+
},
432+
{
433+
"allow_nil?": true,
434+
"default": "nil",
435+
"generated?": false,
436+
"precision": null,
437+
"primary_key?": false,
438+
"references": {
439+
"deferrable": false,
440+
"destination_attribute": "id",
441+
"destination_attribute_default": null,
442+
"destination_attribute_generated": null,
443+
"index?": false,
444+
"match_type": null,
445+
"match_with": null,
446+
"multitenancy": {
447+
"attribute": null,
448+
"global": null,
449+
"strategy": null
450+
},
451+
"name": "posts_organization_id_fkey",
452+
"on_delete": null,
453+
"on_update": null,
454+
"primary_key?": true,
455+
"schema": "public",
456+
"table": "orgs"
457+
},
458+
"scale": null,
459+
"size": null,
460+
"source": "organization_id",
461+
"type": "uuid"
462+
},
463+
{
464+
"allow_nil?": true,
465+
"default": "nil",
466+
"generated?": false,
467+
"precision": null,
468+
"primary_key?": false,
469+
"references": {
470+
"deferrable": false,
471+
"destination_attribute": "id",
472+
"destination_attribute_default": null,
473+
"destination_attribute_generated": null,
474+
"index?": false,
475+
"match_type": null,
476+
"match_with": null,
477+
"multitenancy": {
478+
"attribute": null,
479+
"global": null,
480+
"strategy": null
481+
},
482+
"name": "posts_parent_post_id_fkey",
483+
"on_delete": null,
484+
"on_update": null,
485+
"primary_key?": true,
486+
"schema": "public",
487+
"table": "posts"
488+
},
489+
"scale": null,
490+
"size": null,
491+
"source": "parent_post_id",
492+
"type": "uuid"
493+
},
494+
{
495+
"allow_nil?": true,
496+
"default": "nil",
497+
"generated?": false,
498+
"precision": null,
499+
"primary_key?": false,
500+
"references": {
501+
"deferrable": false,
502+
"destination_attribute": "id",
503+
"destination_attribute_default": null,
504+
"destination_attribute_generated": null,
505+
"index?": false,
506+
"match_type": null,
507+
"match_with": null,
508+
"multitenancy": {
509+
"attribute": null,
510+
"global": null,
511+
"strategy": null
512+
},
513+
"name": "posts_author_id_fkey",
514+
"on_delete": null,
515+
"on_update": null,
516+
"primary_key?": true,
517+
"schema": "public",
518+
"table": "authors"
519+
},
520+
"scale": null,
521+
"size": null,
522+
"source": "author_id",
523+
"type": "uuid"
524+
},
525+
{
526+
"allow_nil?": true,
527+
"default": "nil",
528+
"generated?": false,
529+
"precision": null,
530+
"primary_key?": false,
531+
"references": {
532+
"deferrable": false,
533+
"destination_attribute": "id",
534+
"destination_attribute_default": null,
535+
"destination_attribute_generated": null,
536+
"index?": false,
537+
"match_type": null,
538+
"match_with": null,
539+
"multitenancy": {
540+
"attribute": null,
541+
"global": null,
542+
"strategy": null
543+
},
544+
"name": "posts_db_point_id_fkey",
545+
"on_delete": null,
546+
"on_update": null,
547+
"primary_key?": true,
548+
"schema": "public",
549+
"table": "points"
550+
},
551+
"scale": null,
552+
"size": null,
553+
"source": "db_point_id",
554+
"type": [
555+
"array",
556+
"float"
557+
]
558+
},
559+
{
560+
"allow_nil?": true,
561+
"default": "nil",
562+
"generated?": false,
563+
"precision": null,
564+
"primary_key?": false,
565+
"references": {
566+
"deferrable": false,
567+
"destination_attribute": "id",
568+
"destination_attribute_default": null,
569+
"destination_attribute_generated": null,
570+
"index?": false,
571+
"match_type": null,
572+
"match_with": null,
573+
"multitenancy": {
574+
"attribute": null,
575+
"global": null,
576+
"strategy": null
577+
},
578+
"name": "posts_db_string_point_id_fkey",
579+
"on_delete": null,
580+
"on_update": null,
581+
"primary_key?": true,
582+
"schema": "public",
583+
"table": "string_points"
584+
},
585+
"scale": null,
586+
"size": null,
587+
"source": "db_string_point_id",
588+
"type": "text"
589+
}
590+
],
591+
"base_filter": "type = 'sponsored'",
592+
"check_constraints": [
593+
{
594+
"attribute": [
595+
"price"
596+
],
597+
"base_filter": "type = 'sponsored'",
598+
"check": "price > 0",
599+
"name": "price_must_be_positive"
600+
}
601+
],
602+
"custom_indexes": [
603+
{
604+
"all_tenants?": false,
605+
"concurrently": true,
606+
"error_fields": [
607+
"uniq_custom_one",
608+
"uniq_custom_two"
609+
],
610+
"fields": [
611+
{
612+
"type": "atom",
613+
"value": "uniq_custom_one"
614+
},
615+
{
616+
"type": "atom",
617+
"value": "uniq_custom_two"
618+
}
619+
],
620+
"include": null,
621+
"message": "dude what the heck",
622+
"name": null,
623+
"nulls_distinct": true,
624+
"prefix": null,
625+
"table": null,
626+
"unique": true,
627+
"using": null,
628+
"where": null
629+
}
630+
],
631+
"custom_statements": [],
632+
"has_create_action": true,
633+
"hash": "28B63D8AA18EE499B2A10DFF793995FF00B811F6CB45E01EBFEF15516D305DF8",
634+
"identities": [
635+
{
636+
"all_tenants?": false,
637+
"base_filter": "type = 'sponsored'",
638+
"index_name": "posts_uniq_if_contains_foo_index",
639+
"keys": [
640+
{
641+
"type": "atom",
642+
"value": "uniq_if_contains_foo"
643+
}
644+
],
645+
"name": "uniq_if_contains_foo",
646+
"nils_distinct?": true,
647+
"where": "(uniq_if_contains_foo LIKE '%foo%')"
648+
},
649+
{
650+
"all_tenants?": false,
651+
"base_filter": "type = 'sponsored'",
652+
"index_name": "posts_uniq_on_upper_index",
653+
"keys": [
654+
{
655+
"type": "string",
656+
"value": "(UPPER(uniq_on_upper))"
657+
}
658+
],
659+
"name": "uniq_on_upper",
660+
"nils_distinct?": true,
661+
"where": null
662+
},
663+
{
664+
"all_tenants?": false,
665+
"base_filter": "type = 'sponsored'",
666+
"index_name": "posts_uniq_one_and_two_index",
667+
"keys": [
668+
{
669+
"type": "atom",
670+
"value": "uniq_one"
671+
},
672+
{
673+
"type": "atom",
674+
"value": "uniq_two"
675+
}
676+
],
677+
"name": "uniq_one_and_two",
678+
"nils_distinct?": true,
679+
"where": null
680+
}
681+
],
682+
"multitenancy": {
683+
"attribute": null,
684+
"global": null,
685+
"strategy": null
686+
},
687+
"repo": "Elixir.AshPostgres.TestRepo",
688+
"schema": null,
689+
"table": "posts"
690+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
defmodule AshPostgres.TestRepo.Migrations.MigrateResources56 do
2+
@moduledoc """
3+
Updates resources based on their most recent snapshots.
4+
5+
This file was autogenerated with `mix ash_postgres.generate_migrations`
6+
"""
7+
8+
use Ecto.Migration
9+
10+
def up do
11+
alter table(:posts) do
12+
add(:is_special, :boolean, null: false, default: true)
13+
end
14+
end
15+
16+
def down do
17+
alter table(:posts) do
18+
remove(:is_special)
19+
end
20+
end
21+
end

‎test/filter_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,39 @@
3434

3535
assert String.contains?(query, "(p0.\"version\"::bigint = $2::bigint)")
3636
end
37+
38+
test "it uses coalesce to optimize the || operator for non-booleans" do
39+
{query, _vars} =
40+
Post
41+
|> Ash.Query.filter((version || 10) == 20)
42+
|> Ash.data_layer_query!()
43+
|> Map.get(:query)
44+
|> then(&AshPostgres.TestRepo.to_sql(:all, &1))
45+
46+
assert String.contains?(query, "(coalesce(p0.\"version\"::bigint, $2::bigint)")
47+
end
48+
49+
test "it uses OR to optimize the || operator for booleans" do
50+
{query, _vars} =
51+
Post
52+
|> Ash.Query.filter(is_special || true)
53+
|> Ash.data_layer_query!()
54+
|> Map.get(:query)
55+
|> then(&AshPostgres.TestRepo.to_sql(:all, &1))
56+
57+
assert String.contains?(query, "(p0.\"is_special\"::boolean OR $2::boolean)")
58+
end
59+
60+
test "it uses AND to optimize the && operator for booleans" do
61+
{query, _vars} =
62+
Post
63+
|> Ash.Query.filter(is_special && public)
64+
|> Ash.data_layer_query!()
65+
|> Map.get(:query)
66+
|> then(&AshPostgres.TestRepo.to_sql(:all, &1))
67+
68+
assert String.contains?(query, "(p0.\"is_special\"::boolean AND p0.\"public\"::boolean)")
69+
end
3770
end
3871

3972
describe "ci_string argument casting" do

‎test/support/resources/post.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ defmodule AshPostgres.Test.Post do
509509
attribute(:limited_score, :integer, public?: true, constraints: [min: 0, max: 100])
510510

511511
attribute(:public, :boolean, public?: true)
512+
attribute(:is_special, :boolean, public?: true, allow_nil?: false, default: true)
512513
attribute(:category, CiCategory, public?: true)
513514
attribute(:type, :atom, default: :sponsored, writable?: false, public?: false)
514515
attribute(:price, :integer, public?: true)

0 commit comments

Comments
 (0)
Please sign in to comment.