Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1cce277

Browse files
committed
improvement: supportlist aggregate
1 parentbad433d commit1cce277

File tree

5 files changed

+147
-27
lines changed

5 files changed

+147
-27
lines changed

‎lib/data_layer.ex‎

Lines changed: 92 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,16 +1076,7 @@ defmodule AshPostgres.DataLayer do
10761076
binding,
10771077
%{load:nil}=aggregate
10781078
)do
1079-
accessed=
1080-
ifaggregate.kind==:firstdo
1081-
{:fragment,[],
1082-
[
1083-
expr:{{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]},
1084-
raw:"[1]"
1085-
]}
1086-
else
1087-
{{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]}
1088-
end
1079+
accessed={{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]}
10891080

10901081
field=
10911082
{:type,[],
@@ -1101,7 +1092,11 @@ defmodule AshPostgres.DataLayer do
11011092
{:coalesce,[],
11021093
[
11031094
field,
1104-
aggregate.default_value
1095+
{:type,[],
1096+
[
1097+
aggregate.default_value,
1098+
Ash.Type.ecto_type(aggregate.type)
1099+
]}
11051100
]}
11061101
end
11071102

@@ -1118,17 +1113,7 @@ defmodule AshPostgres.DataLayer do
11181113
binding,
11191114
%{load:load_as}=aggregate
11201115
)do
1121-
accessed=
1122-
ifaggregate.kind==:firstdo
1123-
{:fragment,[],
1124-
[
1125-
raw:"",
1126-
expr:{{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]},
1127-
raw:"[1]"
1128-
]}
1129-
else
1130-
{{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]}
1131-
end
1116+
accessed={{:.,[],[{:&,[],[binding]},aggregate.name]},[],[]}
11321117

11331118
field=
11341119
{:type,[],
@@ -1144,7 +1129,11 @@ defmodule AshPostgres.DataLayer do
11441129
{:coalesce,[],
11451130
[
11461131
field,
1147-
aggregate.default_value
1132+
{:type,[],
1133+
[
1134+
aggregate.default_value,
1135+
Ash.Type.ecto_type(aggregate.type)
1136+
]}
11481137
]}
11491138
end
11501139

@@ -1204,7 +1193,85 @@ defmodule AshPostgres.DataLayer do
12041193
end
12051194
end
12061195

1207-
defpadd_subquery_aggregate_select(query,%{kind::first}=aggregate,_resource)do
1196+
defpadd_subquery_aggregate_select(query,%{kind:kind}=aggregate,_resource)
1197+
whenkindin[:first,:list]do
1198+
query=default_bindings(query,aggregate.resource)
1199+
key=aggregate.field
1200+
type=Ash.Type.ecto_type(aggregate.type)
1201+
1202+
field=
1203+
ifaggregate.query&&aggregate.query.sort&&aggregate.query.sort!=[]do
1204+
sort_expr=
1205+
aggregate.query.sort
1206+
|>Enum.map(fn{sort,order}->
1207+
caseorder_to_postgres_order(order)do
1208+
nil->
1209+
[expr:{{:.,[],[{:&,[],[0]},sort]},[],[]}]
1210+
1211+
order->
1212+
[expr:{{:.,[],[{:&,[],[0]},sort]},[],[]},raw:order]
1213+
end
1214+
end)
1215+
|>Enum.intersperse(raw:", ")
1216+
|>List.flatten()
1217+
1218+
{:fragment,[],
1219+
[
1220+
raw:"array_agg(",
1221+
expr:{{:.,[],[{:&,[],[0]},key]},[],[]},
1222+
raw:" ORDER BY "
1223+
]++
1224+
sort_expr++[raw:")"]}
1225+
else
1226+
{:fragment,[],
1227+
[
1228+
raw:"array_agg(",
1229+
expr:{{:.,[],[{:&,[],[0]},key]},[],[]},
1230+
raw:")"
1231+
]}
1232+
end
1233+
1234+
{params,filtered}=
1235+
ifaggregate.query&&aggregate.query.filter&&
1236+
notmatch?(%Ash.Filter{expression:nil},aggregate.query.filter)do
1237+
{params,expr}=
1238+
filter_to_expr(
1239+
aggregate.query.filter,
1240+
query.__ash_bindings__.bindings,
1241+
query.select.params
1242+
)
1243+
1244+
{params,{:filter,[],[field,expr]}}
1245+
else
1246+
{[],field}
1247+
end
1248+
1249+
casted=
1250+
ifkind==:firstdo
1251+
{:type,[],
1252+
[
1253+
{:fragment,[],
1254+
[
1255+
raw:"(",
1256+
expr:filtered,
1257+
raw:")[1]"
1258+
]},
1259+
type
1260+
]}
1261+
else
1262+
{:type,[],
1263+
[
1264+
filtered,
1265+
{:array,type}
1266+
]}
1267+
end
1268+
1269+
new_expr={:merge,[],[query.select.expr,{:%{},[],[{aggregate.name,casted}]}]}
1270+
1271+
%{query|select:%{query.select|expr:new_expr,params:params}}
1272+
end
1273+
1274+
defpadd_subquery_aggregate_select(query,%{kind::list}=aggregate,_resource)do
12081275
query=default_bindings(query,aggregate.resource)
12091276
key=aggregate.field
12101277
type=Ash.Type.ecto_type(aggregate.type)
@@ -1229,7 +1296,7 @@ defmodule AshPostgres.DataLayer do
12291296
[
12301297
raw:"array_agg(",
12311298
expr:{{:.,[],[{:&,[],[0]},key]},[],[]},
1232-
raw:"ORDER BY "
1299+
raw:"ORDER BY "
12331300
]++
12341301
sort_expr++[raw:")"]}
12351302
else

‎mix.exs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ defmodule AshPostgres.MixProject do
9595
{:ecto_sql,"~> 3.5"},
9696
{:jason,"~> 1.0"},
9797
{:postgrex,">= 0.0.0"},
98-
{:ash,ash_version("~> 1.41 and >= 1.41.8")},
98+
{:ash,ash_version("~> 1.41 and >= 1.41.11")},
9999
{:git_ops,"~> 2.0.1",only::dev},
100100
{:ex_doc,"~> 0.22",only::dev,runtime:false},
101101
{:ex_check,"~> 0.11.0",only::dev},

‎mix.lock‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%{
2-
"ash":{:hex,:ash,"1.41.8","91a506b03a3efd75576ac7e20234a5af09f02e3594c2503007c3fc91fe0deca1",[:mix],[{:comparable,"~> 1.0",[hex::comparable,repo:"hexpm",optional:false]},{:decimal,"~> 2.0",[hex::decimal,repo:"hexpm",optional:false]},{:ecto,"~> 3.4",[hex::ecto,repo:"hexpm",optional:false]},{:ets,"~> 0.8.0",[hex::ets,repo:"hexpm",optional:false]},{:jason,">= 1.0.0",[hex::jason,repo:"hexpm",optional:false]},{:nimble_options,"~> 0.3.5",[hex::nimble_options,repo:"hexpm",optional:false]},{:picosat_elixir,"~> 0.1.5",[hex::picosat_elixir,repo:"hexpm",optional:false]},{:timex,">= 3.0.0",[hex::timex,repo:"hexpm",optional:false]}],"hexpm","7806859710109ba2a96fbcfdf3429b2290af74e3b6d6f2ca04e44bbd3b93559c"},
2+
"ash":{:hex,:ash,"1.41.11","55b8a747222e8e6879931482db5f626f857c6a35a97c85f6d5e1a55c2a349fef",[:mix],[{:comparable,"~> 1.0",[hex::comparable,repo:"hexpm",optional:false]},{:decimal,"~> 2.0",[hex::decimal,repo:"hexpm",optional:false]},{:ecto,"~> 3.4",[hex::ecto,repo:"hexpm",optional:false]},{:ets,"~> 0.8.0",[hex::ets,repo:"hexpm",optional:false]},{:jason,">= 1.0.0",[hex::jason,repo:"hexpm",optional:false]},{:nimble_options,"~> 0.3.5",[hex::nimble_options,repo:"hexpm",optional:false]},{:picosat_elixir,"~> 0.1.5",[hex::picosat_elixir,repo:"hexpm",optional:false]},{:timex,">= 3.0.0",[hex::timex,repo:"hexpm",optional:false]}],"hexpm","fa17390ea3892966d560eece121270eadffda97da51eca3e25ce09e3438452fc"},
33
"bunt":{:hex,:bunt,"0.2.0","951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38",[:mix],[],"hexpm","7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
44
"certifi":{:hex,:certifi,"2.6.1","dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493",[:rebar3],[],"hexpm","524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"},
55
"combine":{:hex,:combine,"0.10.0","eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f",[:mix],[],"hexpm","1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},

‎test/aggregate_test.exs‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,55 @@ defmodule AshPostgres.AggregateTest do
7777
end
7878
end
7979

80+
describe"list"do
81+
test"with no related data it returns an empty list"do
82+
post=
83+
Post
84+
|>Ash.Changeset.new(%{title:"title"})
85+
|>Api.create!()
86+
87+
assert%{comment_titles:[]}=
88+
Post
89+
|>Ash.Query.filter(id==^post.id)
90+
|>Ash.Query.load(:comment_titles)
91+
|>Api.read_one!()
92+
end
93+
94+
test"with related data, it returns the value"do
95+
post=
96+
Post
97+
|>Ash.Changeset.new(%{title:"title"})
98+
|>Api.create!()
99+
100+
Comment
101+
|>Ash.Changeset.new(%{title:"bbb"})
102+
|>Ash.Changeset.replace_relationship(:post,post)
103+
|>Api.create!()
104+
105+
Comment
106+
|>Ash.Changeset.new(%{title:"ccc"})
107+
|>Ash.Changeset.replace_relationship(:post,post)
108+
|>Api.create!()
109+
110+
assert%{comment_titles:["bbb","ccc"]}=
111+
Post
112+
|>Ash.Query.filter(id==^post.id)
113+
|>Ash.Query.load(:comment_titles)
114+
|>Api.read_one!()
115+
116+
Comment
117+
|>Ash.Changeset.new(%{title:"aaa"})
118+
|>Ash.Changeset.replace_relationship(:post,post)
119+
|>Api.create!()
120+
121+
assert%{comment_titles:["aaa","bbb","ccc"]}=
122+
Post
123+
|>Ash.Query.filter(id==^post.id)
124+
|>Ash.Query.load(:comment_titles)
125+
|>Api.read_one!()
126+
end
127+
end
128+
80129
describe"first"do
81130
test"with no related data it returns nil"do
82131
post=

‎test/support/resources/post.ex‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ defmodule AshPostgres.Test.Post do
6868
sort(title::asc_nils_last)
6969
end
7070

71+
list:comment_titles,:comments,:titledo
72+
sort(title::asc_nils_last)
73+
end
74+
7175
sum(:sum_of_comment_likes,:comments,:likes)
7276

7377
sum:sum_of_comment_likes_called_match,:comments,:likesdo

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp