Skip to content

Commit edc0746

Browse files
committed
added getfield tests to expression conversion
1 parent 22a43d4 commit edc0746

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

tests/expression_converter_/test_match_conversion.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,69 @@ def test_deeply_nested_logical_operator_with_variable(self):
214214
}
215215
]
216216
self.assertOptimizerEqual(expr, expected)
217+
218+
def test_getfield_usage_on_dual_binary_operator(self):
219+
expr = {
220+
"$expr": {
221+
"$gt": [
222+
{"$getField": {"input": "$price", "field": "value"}},
223+
{"$getField": {"input": "$discounted_price", "field": "value"}},
224+
]
225+
}
226+
}
227+
expected = [
228+
{
229+
"$match": {
230+
"$expr": {
231+
"$gt": [
232+
{"$getField": {"input": "$price", "field": "value"}},
233+
{"$getField": {"input": "$discounted_price", "field": "value"}},
234+
]
235+
}
236+
}
237+
}
238+
]
239+
self.assertOptimizerEqual(expr, expected)
240+
241+
def test_getfield_usage_on_onesided_binary_operator(self):
242+
expr = {"$expr": {"$gt": [{"$getField": {"input": "$price", "field": "value"}}, 100]}}
243+
# This should create a proper match condition with no $expr
244+
expected = {"price.value": {"$gt": 100}}
245+
self.assertOptimizerEqual(expr, expected)
246+
247+
def test_nested_getfield_usage_on_onesided_binary(self):
248+
expr = {
249+
"$expr": {
250+
"$gt": [
251+
{
252+
"$getField": {
253+
"input": {"$getField": {"input": "$item", "field": "price"}},
254+
"field": "value",
255+
}
256+
},
257+
100,
258+
]
259+
}
260+
}
261+
expected = {"item.price.value": {"$gt": 100}}
262+
self.assertOptimizerEqual(expr, expected)
263+
264+
def test_getfield_with_non_constant_field(self):
265+
expr = {"$expr": {"$gt": [{"$getField": {"input": "$price", "field": "$field_name"}}, 100]}}
266+
self.assertOptimizerEqual(expr, expr)
267+
268+
def test_getfield_with_object_non_simple_input(self):
269+
expr = {
270+
"$expr": {
271+
"$gt": [
272+
{
273+
"$getField": {
274+
"input": {"$literal": "$item"},
275+
"field": "price",
276+
}
277+
},
278+
100,
279+
]
280+
}
281+
}
282+
self.assertOptimizerEqual(expr, expr)

tests/expression_converter_/test_op_expressions.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,45 @@ def test_eq_conversion_various_types(self):
7474
def test_eq_conversion_various_array_types(self):
7575
self._test_conversion_various_types(self._test_eq_conversion_valid_array_type)
7676

77+
def test_eq_conversion_getfield(self):
78+
expr = {"$eq": [{"$getField": {"input": "$item", "field": "age"}}, 10]}
79+
expected = {"item.age": 10}}
80+
self.assertConversionEqual(expr, expected)
81+
82+
def test_eq_conversion_nested_getfield(self):
83+
expr = {
84+
"$eq": [
85+
{
86+
"$getField": {
87+
"input": {"$getField": {"input": "$item", "field": "shelf_life"}},
88+
"field": "age",
89+
}
90+
},
91+
10,
92+
]
93+
}
94+
expected = {"item.shelf_life.age": 10}}
95+
self.assertConversionEqual(expr, expected)
96+
97+
def test_eq_conversion_dual_getfield_ineligible(self):
98+
expr = {
99+
"$eq": [
100+
{
101+
"$getField": {
102+
"input": {"$getField": {"input": "$item", "field": "shelf_life"}},
103+
"field": "age",
104+
}
105+
},
106+
{
107+
"$getField": {
108+
"input": {"$getField": {"input": "$item", "field": "shelf_life"}},
109+
"field": "age",
110+
}
111+
},
112+
]
113+
}
114+
self.assertNotOptimizable(expr)
115+
77116

78117
class TestInExprConversion(ExpressionConversionTestCase):
79118
def test_in_conversion(self):
@@ -112,6 +151,46 @@ def test_in_conversion_various_types(self):
112151
with self.subTest(_type=_type, val=val):
113152
self._test_in_conversion_valid_type(val)
114153

154+
def test_in_conversion_getfield(self):
155+
expr = {"$in": [{"$getField": {"input": "$item", "field": "age"}}, [10]]}
156+
expected = {"item.age": {"$in": [10]}}
157+
self.assertConversionEqual(expr, expected)
158+
159+
def test_in_conversion_nested_getfield(self):
160+
expr = {
161+
"$in": [
162+
{
163+
"$getField": {
164+
"input": {"$getField": {"input": "$item", "field": "shelf_life"}},
165+
"field": "age",
166+
}
167+
},
168+
10,
169+
]
170+
}
171+
expected = {"item.shelf_life.age": {"$in": [10]}}
172+
self.assertConversionEqual(expr, expected)
173+
174+
def test_in_conversion_dual_getfield_ineligible(self):
175+
expr = {
176+
"$in": [
177+
{
178+
"$getField": {
179+
"input": "$root",
180+
"field": "age",
181+
}
182+
},
183+
[{
184+
"$getField": {
185+
"input": "$value",
186+
"field": "age",
187+
}
188+
}],
189+
]
190+
}
191+
self.assertNotOptimizable(expr)
192+
193+
115194

116195
class TestLogicalExpressionConversion(ExpressionConversionTestCase):
117196
def test_logical_and_conversion(self):
@@ -173,6 +252,7 @@ def test_logical_mixed_conversion(self):
173252
{"$in": ["$category", ["electronics", "books"]]},
174253
{"$eq": ["$verified", True]},
175254
{"$lte": ["$price", 2000]},
255+
{"$eq": [{"$getField": {"input": "$root", "field": "age"}}, 10]}
176256
]
177257
}
178258
expected = {
@@ -181,6 +261,7 @@ def test_logical_mixed_conversion(self):
181261
{"category": {"$in": ["electronics", "books"]}},
182262
{"verified": True},
183263
{"price": {"$lte": 2000}},
264+
{"root.age": 10}
184265
]
185266
}
186267
self.assertConversionEqual(expr, expected)

0 commit comments

Comments
 (0)