Releases: Knetic/govaluate
Short-circuiting, date localization
API Breaks
Multiple API breaks occurred between the previous release and this one. They are minor, and most users won't see any impact, but they measurably change the public interface and semantic meaning of some expressions.
Date localization
Previously, literal dates were parsed as UTC dates and always turned into the same value no matter what locale the expression ran. However, this quickly led to confusing situations where users would pass time.Now()
(which is localized) as a parameter, compare it against a literal date (which was not localized) and would see results that seemed wrong. For example, on December 31st, 2015, at 9:00pm in Pacific Time, the expression now > '2016-01-01'
would evaluate to true
.
Per #49 , all literal dates are parsed in the current locale (unless they explicitly include the locale in the date string).
GetTokenKindString
removed
Previously, an exported function called GetTokenKindString
existed. It has been removed, and is exactly replaced by the String()
function, which can be called from any OperatorToken
. This makes it more idiomatic, and also matches the convention used elsewhere in the library. See #37
Privatized constants
The library used to expose a lot of constants which weren't useful to users, and were only used internally (mostly for stage planning). Some of them weren't even used at all. These have been privatized or removed. See #38
Features
- Short-circuiting is now implemented in cases where both sides of an operation don't need to be known in order for the operation to complete. See #36 and #53 .
complex
andstruct
types can now be passed as parameters. Before expression functions were available, these types made no sense in an expression. However, they can be perfectly valid now. See #57
Version tags
This entire repo has been re-tagged to match the gopkg.in standard. This means that instead of import "github.com/Knetic/govaluate"
(which always pulls master branch), users can now pin to a specific released version by doing import "gopkg.in/Knetic/govaluate.v3"
- where v3
is the tag of the major release that you'd like.
Literal eliding
Features
- Where an expression has an operator that will only ever work on literals, the library will now elide the operator and optimize the literals into a single stage ( #35 ) instead of doing so upon every call to
Evaluate()
(involves bugfixes on this feature from #46 and #47 )
Bugs
- Fixed a bug where expression parsing would panic if they started with
)
(found with #47) - Fixed a bug where evaluation would panic if parameters contained incomparable types and the expression tried to compare them (found with #47)
- Fixed a bug where parsing would try to optimize tokens before checking grammar, leading to panics with regex operators being used as EOF (found with #47).
Lexicographic compare, unchecked mode
Features
- Lexicographic compare ( #29 )
- Added "unchecked" mode to expressions. After parsing,
EvaluableExpresion.ChecksTypes
can be set tofalse
, which will cause all furtherEval
orEvaluate
calls to ignore type checking, and instead panic if types are not valid. This should only be used by those who can guarantee that their types will never be invalid for the operators they're using them with. See #24 for some notes on cost/benefit.
Bugs
- Fixed bug where precedence of functions without parameters was off ( #28 )
- Fixed bug where many consecutive logical operators would evaluate out of order ( #30 )
- Fixed bug where nested ternaries would evaluate in wrong order ( #32 )
Misc
- Performance improvements when dealing with bools ( #33 )
Expression Functions
Features
- Support for user-defined functions that can be run during evaluation ( #25 )
- Null coalescence operator ( #23 )
- Array membership operator ( #26 )
- Added ability for expressions to be created from an array of ExpressionTokens, rather than a string (useful for those who want to generate expressions dynamically, or from other parsers).
Bugs
- Fixed a bug where strings that were the same as modifiers would be erroneously treated as modifiers ( #22 )
- Fixed a bug where numeric literals with multiple radixes (radices?) would fail to parse, and turn into
nil
instead of returning an error.
ToSQLQuery()
has also been greatly modernized to include all operators/modifiers/comparators except for ternaries.
This release is contract-compatible with previous releases.
API-break, bitwise operators, evaluation speed
API Break
Previously, the ^
operator stood for "exponent", it now means "bitwise-XOR". The exponent operator is now **
, in line with the Ruby style (since it's the only language which seems to have an operator for that). This will break expressions that worked in 1.x. Before upgrading to the 2.x, check to see if you have any expressions which use the ^
operator, and change them to **
. There is no automatic checking for this, no switching for the semantics. You need to do an audit on your own, or your expressions may not evaluate how you expect.
It is not expected that any similar API breaks will happen in the future, this one was only due to author's oversight early in development. See #20 for some discussion of the change.
Features
- Bitwise operators ( #18 #19 )
- Dramatically improved evaluation speed at the slight cost of more memory usage and slightly slower parse times. This change is net-neutral in speed if an expression is only evaluated once, but if a parsed
EvaluableExpression
is ever re-used, the gains will be apparent.
Bugs
- Fixed case where multiple consecutive operators of equal precedence would evaluate in backwards order ( #21 ).
Ternary operator, String concat, Parameter flexibility
Features
- Implemented ternary operator ( #12 and #17 )
- Implemented string concatenation ( #13 )
- Parameters can now be specified as structures other than
map[string]interface{}
. Anything that exposes aGet(string)(interface{}, error)
method receiver can now be passed intoEval
. ( #14 )
Enhancements
- Optimized regex compilation. When a regex is used against a constant string, that string is compiled at parsing-time, not evaluation-time. Also allowed a
*regexp.Regexp
object to be passed in as a parameter, and used as the pattern for a regex. Strings used as patterns are still supported, but will be compiled during each evaluation, and therefore slower. ( #16 )
Type safety, regex
Features
- Made sure that evaluation fails if any parameter is a struct or complex float (neither of which can be meaningfully evaluated)
- Implemented explicit type-checking of parameters at runtime. No longer will the library panic when
foo > 5
is given astring
forfoo
, an error is returned instead. (#11) - Implemented regex and not-regex operators (
=~
and!~
) which operate on strings. Implementation largely courtesy vjeantet.
Bugs
Internationalization, Bugfixes, benchmarks
Implemented parsing for >1byte runes everywhere (means the entire utf8 range is open for use)
Fixed panics when using fixed-point parameters during evaluation
Fixed parsing error when parsing variables that contained underscores, such as when using used snake_case.
Fixed bugs which prevented using comparators after a clause, previously expressions like "(2 + 2) >= 4" would fail to parse
Added some benchmarks (go test -bench=.)
Added operator prefixes, escaping, and sql query translation
Operator prefixes ("!" for boolean inversion, and "-" for numeric negation) implemented.
Backslashes for escaping special characters implemented.
Escaped parameters implemented (so that parameters with minus signs or spaces in their names can be used).
Also implemented the ability to translate a valid govaluate expression into a SQL "where" clause, as a string. Support for MongoDB queries is experimental.
Contract-compatible with prior releases; expressions and code written for previous versions will operate exactly the same with this release.
Expanded type parsing, added dates
Implemented date parsing/evaluation. Also implemented exponential and modulus operators.
Contract-compatible with prior releases.