Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort NULL values like an empty string. #104

Merged
merged 1 commit into from
Jun 18, 2024
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
6 changes: 3 additions & 3 deletions arg_parser/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (self *storedQueryWrapper) Eval(ctx context.Context, scope types.Scope) <-c
if slice.Type().Kind() == reflect.Slice {
for i := 0; i < slice.Len(); i++ {
value := slice.Index(i).Interface()
if !types.IsNullObject(value) {
if !types.IsNil(value) {
select {
case <-ctx.Done():
return
Expand All @@ -184,7 +184,7 @@ func (self *storedQueryWrapper) Eval(ctx context.Context, scope types.Scope) <-c
}
} else {
row_value := self.toRow(scope, self.value)
if !types.IsNullObject(row_value) {
if !types.IsNil(row_value) {
select {
case <-ctx.Done():
return
Expand All @@ -198,7 +198,7 @@ func (self *storedQueryWrapper) Eval(ctx context.Context, scope types.Scope) <-c
}

func (self *storedQueryWrapper) toRow(scope types.Scope, value types.Any) types.Row {
if types.IsNullObject(value) {
if types.IsNil(value) {
return types.Null{}
}

Expand Down
3 changes: 1 addition & 2 deletions arg_parser/args_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"www.velocidex.com/golang/vfilter/arg_parser"
"www.velocidex.com/golang/vfilter/scope"
"www.velocidex.com/golang/vfilter/types"
"www.velocidex.com/golang/vfilter/utils"
"www.velocidex.com/golang/vfilter/utils/dict"
)

Expand Down Expand Up @@ -185,7 +184,7 @@ func (self argFunc) Call(ctx context.Context, scope types.Scope, args *ordereddi
result.Set("dict", arg.Dict)
}

if !utils.IsNil(arg.Any) {
if !types.IsNil(arg.Any) {
result.Set("any", arg.Any)
result.Set("any type", fmt.Sprintf("%T", arg.Any))

Expand Down
4 changes: 2 additions & 2 deletions arg_parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func sliceDictParser(ctx context.Context, scope types.Scope,
result := []*ordereddict.Dict{}
for i := 0; i < len(new_value); i++ {
item := new_value[i]
if !utils.IsNil(item) {
if !types.IsNil(item) {
result = append(result, dict.RowToDict(ctx, scope, item))
}
}
Expand Down Expand Up @@ -269,7 +269,7 @@ func dictParser(ctx context.Context, scope types.Scope,

// Build the query args
env := ordereddict.NewDict()
if !utils.IsNil(arg) {
if !types.IsNil(arg) {
// Shortcut for actual dicts
dict, ok := arg.(*ordereddict.Dict)
if ok {
Expand Down
5 changes: 2 additions & 3 deletions functions/if.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/Velocidex/ordereddict"
"www.velocidex.com/golang/vfilter/arg_parser"
"www.velocidex.com/golang/vfilter/types"
"www.velocidex.com/golang/vfilter/utils"
)

type _IfFunctionArgs struct {
Expand Down Expand Up @@ -38,7 +37,7 @@ func (self _IfFunction) Call(
}

if scope.Bool(arg.Condition) {
if utils.IsNil(arg.Then) {
if types.IsNil(arg.Then) {
return &types.Null{}
}

Expand All @@ -63,7 +62,7 @@ func (self _IfFunction) Call(
return t
}
}
if utils.IsNil(arg.Else) {
if types.IsNil(arg.Else) {
return &types.Null{}
}

Expand Down
4 changes: 2 additions & 2 deletions protocols/protocol_associative.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (self *AssociativeDispatcher) Associative(
scope types.Scope, a types.Any, b types.Any) (types.Any, bool) {
ctx := context.Background()

if utils.IsNil(a) {
if types.IsNil(a) {
return types.Null{}, false
}

Expand Down Expand Up @@ -79,7 +79,7 @@ func (self *AssociativeDispatcher) Associative(

// Do not let naked nils to be retrieved from
// a dict, instead return Null{}
if res == nil || utils.IsNil(res) {
if res == nil || types.IsNil(res) {
res = types.Null{}
}

Expand Down
2 changes: 1 addition & 1 deletion protocols/protocol_eq.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (self EqDispatcher) Eq(scope types.Scope, a types.Any, b types.Any) bool {

switch t := a.(type) {
case types.Null, *types.Null, nil:
return types.IsNullObject(b) // types.Null == types.Null else false
return types.IsNil(b) // types.Null == types.Null else false

case string:
rhs, ok := b.(string)
Expand Down
4 changes: 2 additions & 2 deletions protocols/protocol_iterate.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (self IterateDispatcher) Iterate(
go func() {
defer close(output_chan)

if !types.IsNullObject(a) {
if !types.IsNil(a) {
select {
case <-ctx.Done():
return
Expand Down Expand Up @@ -99,7 +99,7 @@ func _SliceIterator(ctx context.Context, scope types.Scope, a types.Any) <-chan
if a_value.Type().Kind() == reflect.Slice {
for i := 0; i < a_value.Len(); i++ {
value := a_value.Index(i).Interface()
if types.IsNullObject(value) {
if types.IsNil(value) {
continue
}

Expand Down
2 changes: 1 addition & 1 deletion scope/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (self ScopeUnmarshaller) Unmarshal(
unmarshalled, err := unmarshaller.Unmarshal(unmarshaller,
new_scope, v)
if err == nil {
if !utils.IsNil(unmarshalled) {
if !types.IsNil(unmarshalled) {
env.Set(k, unmarshalled)
}
} else {
Expand Down
10 changes: 10 additions & 0 deletions sort/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ func (self *DefaultSorterCtx) Less(i, j int) bool {
return false
}

// Sort NULL like an empty string because normally NULL
// comparisons are not stable.
if types.IsNil(element1) {
element1 = ""
}

if types.IsNil(element2) {
element2 = ""
}

if self.Desc {
return !self.Scope.Lt(element1, element2)
}
Expand Down
9 changes: 8 additions & 1 deletion types/null.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package types

import "reflect"

// A real type which encodes to JSON NULL. Using go's nil is dangerous
// because it forces constant checking for nil pointer dereference. It
// is safer to just return this value when VQL needs to return NULL.
Expand All @@ -13,7 +15,7 @@ func (self Null) String() string {
return "Null"
}

func IsNullObject(a interface{}) bool {
func IsNil(a interface{}) bool {
if a == nil {
return true
}
Expand All @@ -22,6 +24,11 @@ func IsNullObject(a interface{}) bool {
case Null, *Null:
return true
default:
switch reflect.TypeOf(a).Kind() {
case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Slice:
//use of IsNil method
return reflect.ValueOf(a).IsNil()
}
return false
}
}
13 changes: 0 additions & 13 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,6 @@ func IsCallable(method_value reflect.Value, field_name string) bool {
return true
}

func IsNil(i interface{}) bool {
if i == nil {
return true
}

switch reflect.TypeOf(i).Kind() {
case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Slice:
//use of IsNil method
return reflect.ValueOf(i).IsNil()
}
return false
}

func InString(hay *[]string, needle string) bool {
for _, x := range *hay {
if x == needle {
Expand Down
2 changes: 1 addition & 1 deletion vfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -1783,7 +1783,7 @@ func (self *_SymbolRef) callFunction(

// Do not allow nil in VQL since it is not compatible with
// reflect package. The VQL plugin might accidentally pass nil
if utils.IsNil(result) {
if types.IsNil(result) {
return &Null{}
}

Expand Down
Loading