Merge pull request #1365 from niaow/groupby-cluster-rows

CORE-28 Fix GroupBy with a global Rows filter
This commit is contained in:
Nia 2021-01-25 15:37:48 -05:00 committed by GitHub
commit 13c63baa14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 2 deletions

View file

@ -2797,6 +2797,12 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c
}
if hasLimit || hasCol { // we need to perform this query cluster-wide ahead of executeGroupByShard
if idx, ok := child.Args["valueidx"].(int64); ok {
// The rows query was already completed on the initiating node.
childRows[i] = opt.EmbeddedData[idx].Columns()
continue
}
childRows[i], err = e.executeRows(ctx, qcx, index, child, shards, opt)
if err != nil {
return nil, errors.Wrap(err, "getting rows for ")
@ -2804,6 +2810,13 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c
if len(childRows[i]) == 0 { // there are no results because this field has no values.
return &GroupCounts{}, nil
}
// Stuff the result into opt.EmbeddedData so that it gets sent to other nodes in the map-reduce.
// This is flagged as "NoSplit" to ensure that the entire row gets sent out.
rowsRow := NewRow(childRows[i]...)
rowsRow.NoSplit = true
child.Args["valueidx"] = int64(len(opt.EmbeddedData))
opt.EmbeddedData = append(opt.EmbeddedData, rowsRow)
}
}
@ -5527,6 +5540,10 @@ func makeEmbeddedDataForShards(allRows []*Row, shards []uint64) []*Row {
if row == nil || len(row.segments) == 0 {
continue
}
if row.NoSplit {
newRows[i] = row
continue
}
segments := row.segments
segmentIndex := 0
newRows[i] = &Row{

View file

@ -5517,7 +5517,7 @@ func TestExecutor_Execute_DistinctFailure(t *testing.T) {
func TestExecutor_Execute_GroupBy(t *testing.T) {
groupByTest := func(t *testing.T, clusterSize int) {
c := test.MustRunCluster(t, 1)
c := test.MustRunCluster(t, clusterSize)
defer c.Close()
c.CreateField(t, "i", pilosa.IndexOptions{}, "general")
c.CreateField(t, "i", pilosa.IndexOptions{}, "sub")
@ -5924,7 +5924,7 @@ func TestExecutor_Execute_GroupBy(t *testing.T) {
})
}
for size := range []int{1, 3} {
for _, size := range []int{1, 3} {
t.Run(fmt.Sprintf("%d_nodes", size), func(t *testing.T) {
groupByTest(t, size)
})

View file

@ -388,6 +388,7 @@ var callInfoByFunc = map[string]callInfo{
"from": nil,
"to": nil,
"like": "",
"valueidx": int64(0),
},
},
"Shift": {allowUnknown: false,

4
row.go
View file

@ -42,6 +42,10 @@ type Row struct {
// query. Knowing the index and field, we can figure out how to
// interpret the row data.
Field string
// NoSplit indicates that this row may not be split.
// This is used for `Rows` calls in a GroupBy.
NoSplit bool
}
// NewRow returns a new instance of Row.