mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
Add support for field != null Range query
This commit is contained in:
parent
07ae881967
commit
4304d341f7
7 changed files with 44 additions and 3 deletions
25
executor.go
25
executor.go
|
|
@ -715,7 +715,30 @@ func (e *Executor) executeFieldRangeSlice(ctx context.Context, index string, c *
|
|||
fieldName, cond = k, vv
|
||||
}
|
||||
|
||||
if cond.Op == pql.BETWEEN {
|
||||
// EQ null (not implemented: flip frag.FieldNotNull with max ColumnID)
|
||||
// NEQ null frag.FieldNotNull()
|
||||
// BETWEEN a,b(in) BETWEEN/frag.FieldRangeBetween()
|
||||
// BETWEEN a,b(out) BETWEEN/frag.FieldNotNull()
|
||||
// EQ <int> frag.FieldRange
|
||||
// NEQ <int> (not implemented: frag.FieldRange)
|
||||
|
||||
// Handle `!= null`.
|
||||
if cond.Op == pql.NEQ && cond.Value == nil {
|
||||
// Find field.
|
||||
field := f.Field(fieldName)
|
||||
if field == nil {
|
||||
return nil, ErrFieldNotFound
|
||||
}
|
||||
|
||||
// Retrieve fragment.
|
||||
frag := e.Holder.Fragment(index, frame, ViewFieldPrefix+fieldName, slice)
|
||||
if frag == nil {
|
||||
return NewBitmap(), nil
|
||||
}
|
||||
|
||||
return frag.FieldNotNull(field.BitDepth())
|
||||
|
||||
} else if cond.Op == pql.BETWEEN {
|
||||
|
||||
predicates, err := cond.IntSliceValue()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -764,6 +764,14 @@ func TestExecutor_Execute_FieldRange(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
t.Run("NEQ", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=other, foo != null)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual([]uint64{0}, result[0].(*pilosa.Bitmap).Bits()) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("LT", func(t *testing.T) {
|
||||
if result, err := e.Execute(context.Background(), "i", test.MustParse(`Range(frame=f, foo < 20)`), nil, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ func (p *Parser) parseArgs() (map[string]interface{}, error) {
|
|||
var op Token
|
||||
switch tok, pos, lit := p.scanIgnoreWhitespace(); tok {
|
||||
case ASSIGN:
|
||||
case EQ, LT, LTE, GT, GTE, BETWEEN:
|
||||
case EQ, NEQ, LT, LTE, GT, GTE, BETWEEN:
|
||||
op = tok
|
||||
default:
|
||||
return nil, parseErrorf(pos, "expected equals sign or comparison operator, found %q", lit)
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ func TestParser_Parse(t *testing.T) {
|
|||
|
||||
// Parse with condition arguments.
|
||||
t.Run("WithCondition", func(t *testing.T) {
|
||||
q, err := pql.ParseString(`MyCall(key=foo, x == 12.25, y >= 100, z >< [4,8])`)
|
||||
q, err := pql.ParseString(`MyCall(key=foo, x == 12.25, y >= 100, z >< [4,8], m != null)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(q.Calls[0],
|
||||
|
|
@ -183,6 +183,7 @@ func TestParser_Parse(t *testing.T) {
|
|||
"x": &pql.Condition{Op: pql.EQ, Value: 12.25},
|
||||
"y": &pql.Condition{Op: pql.GTE, Value: int64(100)},
|
||||
"z": &pql.Condition{Op: pql.BETWEEN, Value: []interface{}{int64(4), int64(8)}},
|
||||
"m": &pql.Condition{Op: pql.NEQ, Value: nil},
|
||||
},
|
||||
},
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,12 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
|
|||
}
|
||||
s.unread()
|
||||
return ASSIGN, pos, string(ch)
|
||||
case '!':
|
||||
if next := s.read(); next == '=' {
|
||||
return NEQ, pos, "!="
|
||||
}
|
||||
s.unread()
|
||||
return ASSIGN, pos, string(ch)
|
||||
case '<':
|
||||
if next := s.read(); next == '=' {
|
||||
return LTE, pos, "<="
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
|
||||
{name: "ASSIGN", s: `=`, tok: pql.ASSIGN, lit: `=`},
|
||||
{name: "EQ", s: `==`, tok: pql.EQ, lit: `==`},
|
||||
{name: "NEQ", s: `!=`, tok: pql.NEQ, lit: `!=`},
|
||||
{name: "LT", s: `<`, tok: pql.LT, lit: `<`},
|
||||
{name: "LTE", s: `<=`, tok: pql.LTE, lit: `<=`},
|
||||
{name: "GT", s: `>`, tok: pql.GT, lit: `>`},
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ const (
|
|||
|
||||
ASSIGN // =
|
||||
EQ // ==
|
||||
NEQ // !=
|
||||
LT // <
|
||||
LTE // <=
|
||||
GT // >
|
||||
|
|
@ -64,6 +65,7 @@ var tokens = [...]string{
|
|||
|
||||
ASSIGN: "=",
|
||||
EQ: "==",
|
||||
NEQ: "!=",
|
||||
LT: "<",
|
||||
LTE: "<=",
|
||||
GT: ">",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue