Skip to content

Commit 0cad8ed

Browse files
[fix] core: return correct elements during parsing
* ensure that deeply nested customizers are supported * correctly increase index when parsing row * include common parameters when expanding query
1 parent 8dc4223 commit 0cad8ed

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

libs/core/garf_core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
'ApiReportFetcher',
2727
]
2828

29-
__version__ = '0.6.2'
29+
__version__ = '0.6.3'

libs/core/garf_core/parsers.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ def _process_customizer_slice(self, row, customizer, field):
150150

151151
def _process_nested_field(self, row, customizer, field):
152152
nested_field = self.get_row_element(row, field)
153+
values_ = str(customizer.value).split('.')
154+
if len(values_) > 1:
155+
new_customizer = query_parser.Customizer(
156+
type='nested_field', value='.'.join(values_[1:])
157+
)
158+
return self._process_nested_field(
159+
row=nested_field, customizer=new_customizer, field=values_[0]
160+
)
153161
if isinstance(nested_field, MutableSequence):
154162
return list(
155163
{
@@ -198,9 +206,10 @@ def parse_row(
198206
result = self.process_virtual_column(row, virtual_column)
199207
elif customizer := self.query_spec.customizers.get(column):
200208
result = self.process_customizer(row, customizer, fields[index])
209+
index += 1
201210
else:
202211
result = self.parse_row_element(row, fields[index])
203-
index = index + 1
212+
index += 1
204213
results.append(result)
205214
return results
206215

libs/core/garf_core/query_editor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ def replace_params_template(
156156
else:
157157
query_text = self.expand_jinja(query_text, {})
158158
if macros := params.macro:
159-
query_text = query_text.format(**macros)
159+
query_text = query_text.format(
160+
**macros, **CommonParametersMixin().common_params
161+
)
160162
logger.debug('Query text after macro substitution:\n%s', query_text)
161163
else:
162164
query_text = self.expand_jinja(query_text, {})

libs/core/tests/unit/test_parsers.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from typing import Union
16+
1517
import pydantic
1618
import pytest
1719
from garf_core import api_clients, parsers, query_editor, query_parser
@@ -21,20 +23,20 @@
2123
).generate()
2224

2325

24-
class NestedResource(pydantic.BaseModel):
25-
nested_element: int
26+
class ArrayElement(pydantic.BaseModel):
27+
element: int = 1
2628

2729

28-
class ArrayElement(pydantic.BaseModel):
29-
element: int
30+
class NestedResource(pydantic.BaseModel):
31+
nested_element: Union[int, list[ArrayElement]] = 1
3032

3133

3234
class FakeProtoMessage(pydantic.BaseModel):
33-
resource: str
34-
resource_id: int
35-
resource_name: str
36-
resource_data: NestedResource
37-
array_data: list[ArrayElement]
35+
resource: str = ''
36+
resource_id: int = 1
37+
resource_name: str = ''
38+
resource_data: NestedResource = NestedResource()
39+
array_data: list[ArrayElement] = pydantic.Field(default_factory=list)
3840

3941

4042
class TestDictParser:
@@ -229,7 +231,8 @@ def test_parser(self):
229231
resource_id + 1 AS next_resource_id,
230232
resource_name,
231233
resource_data.nested_element,
232-
array_data[0].element AS slice_element
234+
array_data[0].element AS slice_element,
235+
resource_id AS same_resource_id,
233236
FROM test
234237
"""
235238
).generate()
@@ -245,7 +248,7 @@ def test_parse_row_returns_converted_numeric_values(self, test_parser):
245248
)
246249

247250
parsed_row = test_parser.parse_row(test_row)
248-
expected_row = [1, 2, 'test', 10, [100]]
251+
expected_row = [1, 2, 'test', 10, [100], 1]
249252

250253
assert parsed_row == expected_row
251254

@@ -272,3 +275,23 @@ def test_parse_response_raises_customizer_error_on_missing_nested_attribute(
272275
match='nested field missing_element is missing in row',
273276
):
274277
test_parser.parse_response(test_response)
278+
279+
def test_parse_row_process_deeply_nested_customizer(self):
280+
spec = query_editor.QuerySpecification(
281+
"""
282+
SELECT
283+
resource_id,
284+
resource_data:nested_element.element AS numeric_element
285+
FROM test
286+
"""
287+
).generate()
288+
test_parser = parsers.ProtoParser(spec)
289+
test_row = FakeProtoMessage(
290+
resource_id=1,
291+
resource_data=NestedResource(nested_element=[ArrayElement(element=100)]),
292+
)
293+
294+
parsed_row = test_parser.parse_row(test_row)
295+
expected_row = [1, [100]]
296+
297+
assert parsed_row == expected_row

0 commit comments

Comments
 (0)