expr icon indicating copy to clipboard operation
expr copied to clipboard

Array comparison is no longer compatible with lower versions

Open fujiwaram opened this issue 2 years ago • 3 comments

Array comparison behavior is changed from v1.10.0.

e.g.

func main() {
	env := map[string]interface{}{
		"names": []string{"A", "B"},
	}
	code := `["A", "B"] == names`

	program, _ := expr.Compile(code, expr.Env(env))
	output, _ := expr.Run(program, env)
	fmt.Println(output)
}
  • v1.9.0 or before result: true
    []string{“A”, "B"} == []string{"A", "B"}
    
  • v1.10.0 or after result: false
    // internal type is []interface{}, so type mismatch
    []interface{}{“A”, "B"} == []string{"A", "B"}
    

v1.9.0: https://goplay.tools/snippet/tayU9IxLSFz v1.10.0: https://goplay.tools/snippet/Ezau-zbCscu

fujiwaram avatar May 16 '23 08:05 fujiwaram

The bytecode used is OpEqual and uses the same runtime.Equal fn: https://github.com/antonmedv/expr/blob/cb1f3459dd4705b6cbaf43069925d5e2c782fd6b/vm/runtime/generated.go#L11

Nothing is changed there. Can you try to debug?

antonmedv avatar May 16 '23 10:05 antonmedv

I manage to insert the line below before calling reflect.DeepEqual, at the end of runtime.Equal:

fmt.Printf("reflect.DeepEqual(%T, %T) == %v\n", a, b, reflect.DeepEqual(a, b))

v1.14.0 output:

reflect.DeepEqual([]interface {}, []string) == false

v1.9.0 output:

reflect.DeepEqual([]string, []string) == true

I hope it helps

fmarcia avatar Aug 16 '23 12:08 fmarcia

So the problem not with comparison. But with turned off optimisation on converting []any to []string

antonmedv avatar Aug 16 '23 18:08 antonmedv

Fixed! Not it is possible to do deep array comparison in expr.

antonmedv avatar Apr 13 '24 08:04 antonmedv