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

SQE: IN operator does not function as one might expect #1529

Closed
jamesdphillips opened this issue May 14, 2018 · 1 comment
Closed

SQE: IN operator does not function as one might expect #1529

jamesdphillips opened this issue May 14, 2018 · 1 comment

Comments

@jamesdphillips
Copy link
Contributor

jamesdphillips commented May 14, 2018

When using the IN operator the right side (RHS) of the expression must be an instance of []interface. This, for instance, makes it frustrating when working the Subscriptions field ([]string) on the Check and Entity types.

Expected Behavior

I would expect to be able write the expression 'unix' IN entity.Subscriptions, however since the RHS of the expression is a slice of strings, this will always evaluate to false.

Possible Solution

A few possible avenues.

a) Expose a function

  • We could expose a function (eg. sliceContains) that allows the user to check if an identifier has a specified value.
  • To avoid any confusion it may make sense to simply remove IN.
// Example expression
entity.LastSeen > 12345678 && sliceContains(entity.Subscriptions, 'unix')

Drawbacks

  • Lots of type assertions, I guess
  • Functions require extra documentation
  • Without any sort of module/packages/namespaces, we run the risk of identifiers colliding

b) Add to types package

I believe, we potentially could add a type with some helpful methods familiar to those who write Python and Ruby.

type MyStringSlice []string

func (MyStringSlice) Count() int {
  // ...
}

func (MyStringSlice) Contains(interface{}) {
  // ...
}

type Entity struct {
  // ...
  Subscriptions MyStringSlice
  // ...
}
// example expression
entity.LastSeen > 12345678 && entity.Subscriptions.Contains('unix')

Drawbacks

  • Is protobuf going to make this needlessly painful?
  • Accessors feature makes heavy use of reflection
  • Methods require extra documentation

c) Expand govaluate

Update govaluate so that IN operator can handle greater range of expressions.

I figure this could partially be optimized at the planning stage;

  • if the RHS of the expression is an array literal we know the RHS should be cast to []interface
  • if the LHS of the expression is a string, integer, float literal, etc. we know that the RHS should be cast to []string, []int, []float, etc.
  • becomes more tricky when the type of the LHS isn't as easy to infer; eg. (1 + 3 / 6.0) IN myIdentifier
  • (in the planner) becomes nearly impossible when the LHS is an identifier. myIdentifier IN otherIdentifer
// the follow example expression becomes viable
entity.LastSeen > 12345678 && 'unix' IN entity.Subscriptions

Drawbacks

  • Planning and in some cases evaluation likely become a bit slower.
  • Potentially tricky edge cases

Context

  • Initially ran into this while trying to filter entities by subscriptions for the web UI.
  • For what it's worth this behavior is documented in govaluate's MANUAL.
  • Blocks [Web] Entities page: filter #839
@jamesdphillips
Copy link
Contributor Author

Duplicate of #922

@jamesdphillips jamesdphillips marked this as a duplicate of #922 May 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant