From 57de42bb91cc0ec09b5045a9e940394f52eb9b09 Mon Sep 17 00:00:00 2001 From: Matt Jaffee Date: Thu, 2 Mar 2017 16:27:45 -0600 Subject: [PATCH] fix empty queries crashing pilosa --- executor.go | 8 +++++++- executor_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/executor.go b/executor.go index f29fdfe9f..0ba1e7017 100644 --- a/executor.go +++ b/executor.go @@ -265,6 +265,9 @@ func (e *Executor) executeTopNSlice(ctx context.Context, db string, c *pql.Call, // executeDifferenceSlice executes a difference() call for a local slice. func (e *Executor) executeDifferenceSlice(ctx context.Context, db string, c *pql.Call, slice uint64) (*Bitmap, error) { var other *Bitmap + if len(c.Children) == 0 { + return nil, fmt.Errorf("empty Difference query is currently not supported") + } for i, input := range c.Children { bm, err := e.executeBitmapCallSlice(ctx, db, input, slice) if err != nil { @@ -308,6 +311,9 @@ func (e *Executor) executeBitmapSlice(ctx context.Context, db string, c *pql.Cal // executeIntersectSlice executes a intersect() call for a local slice. func (e *Executor) executeIntersectSlice(ctx context.Context, db string, c *pql.Call, slice uint64) (*Bitmap, error) { var other *Bitmap + if len(c.Children) == 0 { + return nil, fmt.Errorf("empty Intersect query is currently not supported") + } for i, input := range c.Children { bm, err := e.executeBitmapCallSlice(ctx, db, input, slice) if err != nil { @@ -382,7 +388,7 @@ func (e *Executor) executeRangeSlice(ctx context.Context, db string, c *pql.Call // executeUnionSlice executes a union() call for a local slice. func (e *Executor) executeUnionSlice(ctx context.Context, db string, c *pql.Call, slice uint64) (*Bitmap, error) { - var other *Bitmap + other := NewBitmap() for i, input := range c.Children { bm, err := e.executeBitmapCallSlice(ctx, db, input, slice) if err != nil { diff --git a/executor_test.go b/executor_test.go index 7cc7af2eb..1ad1fbbbb 100644 --- a/executor_test.go +++ b/executor_test.go @@ -50,6 +50,18 @@ func TestExecutor_Execute_Difference(t *testing.T) { } } +// Ensure an empty difference query behaves properly. +func TestExecutor_Execute_Empty_Difference(t *testing.T) { + idx := MustOpenIndex() + defer idx.Close() + idx.MustCreateFragmentIfNotExists("d", "general", 0).MustSetBits(10, 1) + + e := NewExecutor(idx.Index, NewCluster(1)) + if res, err := e.Execute(context.Background(), "d", MustParse(`Difference()`), nil, nil); err == nil { + t.Fatalf("Empty Difference query should give error, but got %v", res) + } +} + // Ensure an intersect query can be executed. func TestExecutor_Execute_Intersect(t *testing.T) { idx := MustOpenIndex() @@ -70,6 +82,17 @@ func TestExecutor_Execute_Intersect(t *testing.T) { } } +// Ensure an empty intersect query behaves properly. +func TestExecutor_Execute_Empty_Intersect(t *testing.T) { + idx := MustOpenIndex() + defer idx.Close() + + e := NewExecutor(idx.Index, NewCluster(1)) + if res, err := e.Execute(context.Background(), "d", MustParse(`Intersect()`), nil, nil); err == nil { + t.Fatalf("Empty Intersect query should give error, but got %v", res) + } +} + // Ensure a union query can be executed. func TestExecutor_Execute_Union(t *testing.T) { idx := MustOpenIndex() @@ -89,6 +112,20 @@ func TestExecutor_Execute_Union(t *testing.T) { } } +// Ensure an empty union query behaves properly. +func TestExecutor_Execute_Empty_Union(t *testing.T) { + idx := MustOpenIndex() + defer idx.Close() + idx.MustCreateFragmentIfNotExists("d", "general", 0).MustSetBits(10, 0) + + e := NewExecutor(idx.Index, NewCluster(1)) + if res, err := e.Execute(context.Background(), "d", MustParse(`Union()`), nil, nil); err != nil { + t.Fatal(err) + } else if bits := res[0].(*pilosa.Bitmap).Bits(); !reflect.DeepEqual(bits, []uint64{}) { + t.Fatalf("unexpected bits: %+v", bits) + } +} + // Ensure a count query can be executed. func TestExecutor_Execute_Count(t *testing.T) { idx := MustOpenIndex()