Skip to content

Commit 67d9a63

Browse files
authored
feat: render the range expressions to their Postgres operators
2 parents b7e2155 + 22bcd05 commit 67d9a63

1 file changed

Lines changed: 121 additions & 0 deletions

File tree

lib/expr.ex

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ defmodule AshSql.Expr do
3232
Lazy,
3333
Length,
3434
Now,
35+
RangeAdjacent,
36+
RangeContains,
37+
RangeLower,
38+
RangeOverlaps,
39+
RangeUpper,
3540
Rem,
3641
Round,
3742
StartOfDay,
@@ -1167,6 +1172,114 @@ defmodule AshSql.Expr do
11671172
end
11681173
end
11691174

1175+
defp default_dynamic_expr(
1176+
query,
1177+
%RangeOverlaps{arguments: [left, right], embedded?: pred_embedded?},
1178+
bindings,
1179+
embedded?,
1180+
acc,
1181+
_type
1182+
) do
1183+
{[left_type, right_type], _type} =
1184+
determine_types(bindings.sql_behaviour, RangeOverlaps, [left, right], :boolean)
1185+
1186+
{left_expr, acc} =
1187+
range_operand(query, left, left_type, bindings, pred_embedded? || embedded?, acc)
1188+
1189+
{right_expr, acc} =
1190+
range_operand(query, right, right_type, bindings, pred_embedded? || embedded?, acc)
1191+
1192+
{Ecto.Query.dynamic(fragment("(? && ?)", ^left_expr, ^right_expr)), acc}
1193+
end
1194+
1195+
defp default_dynamic_expr(
1196+
query,
1197+
%RangeContains{arguments: [left, right], embedded?: pred_embedded?},
1198+
bindings,
1199+
embedded?,
1200+
acc,
1201+
_type
1202+
) do
1203+
{[left_type, right_type], _type} =
1204+
determine_types(bindings.sql_behaviour, RangeContains, [left, right], :boolean)
1205+
1206+
{left_expr, acc} =
1207+
range_operand(query, left, left_type, bindings, pred_embedded? || embedded?, acc)
1208+
1209+
{right_expr, acc} =
1210+
range_operand(query, right, right_type, bindings, pred_embedded? || embedded?, acc)
1211+
1212+
{Ecto.Query.dynamic(fragment("(? @> ?)", ^left_expr, ^right_expr)), acc}
1213+
end
1214+
1215+
defp default_dynamic_expr(
1216+
query,
1217+
%RangeAdjacent{arguments: [left, right], embedded?: pred_embedded?},
1218+
bindings,
1219+
embedded?,
1220+
acc,
1221+
_type
1222+
) do
1223+
{[left_type, right_type], _type} =
1224+
determine_types(bindings.sql_behaviour, RangeAdjacent, [left, right], :boolean)
1225+
1226+
{left_expr, acc} =
1227+
range_operand(query, left, left_type, bindings, pred_embedded? || embedded?, acc)
1228+
1229+
{right_expr, acc} =
1230+
range_operand(query, right, right_type, bindings, pred_embedded? || embedded?, acc)
1231+
1232+
{Ecto.Query.dynamic(fragment("(? -|- ?)", ^left_expr, ^right_expr)), acc}
1233+
end
1234+
1235+
defp default_dynamic_expr(
1236+
query,
1237+
%RangeLower{arguments: [range], embedded?: pred_embedded?},
1238+
bindings,
1239+
embedded?,
1240+
acc,
1241+
type
1242+
) do
1243+
{[determined_type], type} =
1244+
determine_types(bindings.sql_behaviour, RangeLower, [range], type)
1245+
1246+
{range_expr, acc} =
1247+
do_dynamic_expr(
1248+
query,
1249+
range,
1250+
set_location(bindings, :sub_expr),
1251+
pred_embedded? || embedded?,
1252+
acc,
1253+
determined_type || type
1254+
)
1255+
1256+
{Ecto.Query.dynamic(fragment("lower(?)", ^range_expr)), acc}
1257+
end
1258+
1259+
defp default_dynamic_expr(
1260+
query,
1261+
%RangeUpper{arguments: [range], embedded?: pred_embedded?},
1262+
bindings,
1263+
embedded?,
1264+
acc,
1265+
type
1266+
) do
1267+
{[determined_type], type} =
1268+
determine_types(bindings.sql_behaviour, RangeUpper, [range], type)
1269+
1270+
{range_expr, acc} =
1271+
do_dynamic_expr(
1272+
query,
1273+
range,
1274+
set_location(bindings, :sub_expr),
1275+
pred_embedded? || embedded?,
1276+
acc,
1277+
determined_type || type
1278+
)
1279+
1280+
{Ecto.Query.dynamic(fragment("upper(?)", ^range_expr)), acc}
1281+
end
1282+
11701283
defp default_dynamic_expr(
11711284
query,
11721285
%Length{arguments: [list], embedded?: pred_embedded?},
@@ -3205,6 +3318,14 @@ defmodule AshSql.Expr do
32053318
end
32063319
end
32073320

3321+
defp range_operand(query, operand, nil, bindings, embedded?, acc) do
3322+
do_dynamic_expr(query, operand, set_location(bindings, :sub_expr), embedded?, acc, nil)
3323+
end
3324+
3325+
defp range_operand(query, operand, type, bindings, embedded?, acc) do
3326+
maybe_type_expr(query, operand, set_location(bindings, :sub_expr), embedded?, acc, type)
3327+
end
3328+
32083329
defp extract_list_value(value) when is_list(value), do: {:ok, value}
32093330
defp extract_list_value(%MapSet{} = value), do: {:ok, value}
32103331

0 commit comments

Comments
 (0)