diff --git a/executor.go b/executor.go index a12b34f82..aa5d545a4 100644 --- a/executor.go +++ b/executor.go @@ -2714,6 +2714,14 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c for _, fr := range gc.Group { intersectRows = append(intersectRows, &pql.Call{Name: "Row", Args: map[string]interface{}{fr.Field: fr.RowID}}) } + // apply any filter, if present + if filter != nil { + intersectRows = append(intersectRows, filter) + } + // also intersect with any children of Distinct + if len(aggregate.Children[0].Children) > 0 { + intersectRows = append(intersectRows, aggregate.Children[0].Children[0]) + } countDistinctIntersect := &pql.Call{ Name: "Count", @@ -2732,16 +2740,11 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c }, } - err = e.handlePreCallChildren(ctx, qcx, index, countDistinctIntersect, shards, opt) + aggregateCount, err := e.execute(ctx, qcx, index, &pql.Query{Calls: []*pql.Call{countDistinctIntersect}}, []uint64{}, opt) if err != nil { return nil, err } - - aggregateCount, err := e.executeCount(ctx, qcx, index, countDistinctIntersect, shards, opt) - if err != nil { - return nil, err - } - results[n].Sum = int64(aggregateCount) + results[n].Sum = int64(aggregateCount[0].(uint64)) } } return results, nil diff --git a/executor_test.go b/executor_test.go index a20d60495..54e30447d 100644 --- a/executor_test.go +++ b/executor_test.go @@ -5517,6 +5517,8 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { t.Fatal(err) } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1, v=100)`}); err != nil { t.Fatal(err) + } else if _, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Set(1500000, v=100)`}); err != nil { + t.Fatal(err) } t.Run("No Field List Arguments", func(t *testing.T) { @@ -5581,6 +5583,39 @@ func TestExecutor_Execute_GroupBy(t *testing.T) { test.CheckGroupBy(t, expected, results) }) + t.Run("AggregateCountDistinct", func(t *testing.T) { + expected := []pilosa.GroupCount{ + {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Count: 3, Sum: 2}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 1}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 11}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 0}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 0}, + } + + results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(field=v)))`).Results[0].([]pilosa.GroupCount) + test.CheckGroupBy(t, expected, results) + }) + + t.Run("AggregateCountDistinctFilter", func(t *testing.T) { + expected := []pilosa.GroupCount{ + {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Count: 1, Sum: 1}, + } + + results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), filter=Row(v > 10), aggregate=Count(Distinct(field=v)))`).Results[0].([]pilosa.GroupCount) + test.CheckGroupBy(t, expected, results) + }) + + t.Run("AggregateCountDistinctFilterDistinct", func(t *testing.T) { + expected := []pilosa.GroupCount{ + {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 100}}, Count: 3, Sum: 1}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 10}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 0}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 11}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 0}, + {Group: []pilosa.FieldRow{{Field: "general", RowID: 12}, {Field: "sub", RowID: 110}}, Count: 1, Sum: 0}, + } + + results := c.Query(t, "i", `GroupBy(Rows(general), Rows(sub), aggregate=Count(Distinct(Row(v > 10), field=v)))`).Results[0].([]pilosa.GroupCount) + test.CheckGroupBy(t, expected, results) + }) + t.Run("check field offset no limit", func(t *testing.T) { expected := []pilosa.GroupCount{ {Group: []pilosa.FieldRow{{Field: "general", RowID: 11}}, Count: 2},