Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions flowquery-py/src/parsing/operations/group_by.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ def generate_results(
if node is None:
node = self._root

if mapper_index == 0 and len(node.children) == 0 and len(self.mappers) > 0:
return

if len(node.children) > 0:
for child in node.children.values():
self.mappers[mapper_index].overridden = child.value
Expand Down
15 changes: 15 additions & 0 deletions flowquery-py/tests/compute/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,21 @@ async def test_aggregated_with_and_return(self):
assert results[0] == {"i": 1, "sum": 12}
assert results[1] == {"i": 2, "sum": 12}

@pytest.mark.asyncio
async def test_aggregated_with_on_empty_result_set(self):
"""Test aggregated with on empty result set does not crash."""
runner = Runner(
"""
unwind [] as i
unwind [1, 2] as j
with i, count(j) as cnt
return i, cnt
"""
)
await runner.run()
results = runner.results
assert len(results) == 0

@pytest.mark.asyncio
async def test_aggregated_with_using_collect_and_return(self):
"""Test aggregated with using collect and return."""
Expand Down
46 changes: 27 additions & 19 deletions src/parsing/operations/group_by.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ class GroupBy extends Projection {
}
private map() {
let node: Node = this.current;
for(const mapper of this.mappers) {
for (const mapper of this.mappers) {
const value: any = mapper.value();
let child: Node | undefined = node.children.get(value);
if(child === undefined) {
if (child === undefined) {
child = new Node(value);
node.children.set(value, child);
}
Expand All @@ -62,38 +62,46 @@ class GroupBy extends Projection {
this.current = node;
}
private reduce() {
if(this.current.elements === null) {
this.current.elements = this.reducers.map(reducer => reducer.element());
if (this.current.elements === null) {
this.current.elements = this.reducers.map((reducer) => reducer.element());
}
const elements: AggregationElement[] = this.current.elements;
this.reducers.forEach((reducer, index) => {
reducer.reduce(elements[index]);
});
}
private get mappers(): Expression[] {
if(this._mappers === null) {
if (this._mappers === null) {
this._mappers = [...this._generate_mappers()];
}
return this._mappers;
}
private *_generate_mappers(): Generator<Expression> {
for(const [expression, _] of this.expressions()) {
if(expression.mappable()) {
for (const [expression, _] of this.expressions()) {
if (expression.mappable()) {
yield expression;
}
}
}
private get reducers(): AggregateFunction[] {
if(this._reducers === null) {
this._reducers = this.children.map((child) => {
return (child as Expression).reducers();
}).flat();
if (this._reducers === null) {
this._reducers = this.children
.map((child) => {
return (child as Expression).reducers();
})
.flat();
}
return this._reducers;
}
public *generate_results(mapperIndex: number = 0, node: Node = this.root): Generator<Record<string, any>> {
if(node.children.size > 0) {
for(const child of node.children.values()) {
public *generate_results(
mapperIndex: number = 0,
node: Node = this.root
): Generator<Record<string, any>> {
if (mapperIndex === 0 && node.children.size === 0 && this.mappers.length > 0) {
return;
}
if (node.children.size > 0) {
for (const child of node.children.values()) {
this.mappers[mapperIndex].overridden = child.value;
yield* this.generate_results(mapperIndex + 1, child);
}
Expand All @@ -102,10 +110,10 @@ class GroupBy extends Projection {
this.reducers[reducerIndex].overridden = element.value;
});
const record: Record<string, any> = {};
for(const [expression, alias] of this.expressions()) {
for (const [expression, alias] of this.expressions()) {
record[alias] = expression.value();
}
if(this.where) {
if (this.where) {
yield record;
}
}
Expand All @@ -114,11 +122,11 @@ class GroupBy extends Projection {
this._where = where;
}
public get where(): boolean {
if(this._where === null) {
if (this._where === null) {
return true;
}
return this._where.value();
}
};
}

export default GroupBy;
export default GroupBy;
14 changes: 14 additions & 0 deletions tests/compute/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,20 @@ test("Test aggregated with and return", async () => {
expect(results[1]).toEqual({ i: 2, sum: 12 });
});

test("Test aggregated with on empty result set", async () => {
const runner = new Runner(
`
unwind [] as i
unwind [1, 2] as j
with i, count(j) as cnt
return i, cnt
`
);
await runner.run();
const results = runner.results;
expect(results.length).toBe(0);
});

test("Test aggregated with using collect and return", async () => {
const runner = new Runner(
`
Expand Down