162 Commits

Author SHA1 Message Date
Ville Vesilehto f77322b3fb build: bump Go version requirement to 1.24 (#7839)
Go 1.23 is no longer supported as per Go release policy.

Changes:

- Use Go v1.24.6 as the project SDK requirement
- Apply lint fixes for Go 1.24
- Fix "non-constant format string in call" issues as seen in CI.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-08-24 09:02:09 +02:00
Anders Eknert e43ef0a979 Use any in place of interface{} (#7566)
Earlier this evening I tried to run the Go
[modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize)
analyzer on OPA. That didn't go as planned:

- https://github.com/golang/go/issues/73661
- https://github.com/golang/go/issues/73663

While we wait for that to be fixed, I figured an old-fashioned
search-and-replace across the repo may work for at least the
`interface{}` to `any` conversion. That should help make it easier
to see the other fixes as applied by the modernize tool once it has
had those issues resolved.

Signed-off-by: Anders Eknert <anders@styra.com>
2025-05-12 13:57:48 +02:00
Johan Fylling a179a24c48 v1 API
All packages, except for `cmd` and `internal`, have been moved into a new `v1` root package.

Old packages are kept for backwards-compatibility reasons. All contained code is replaced with simple type aliases and proxy functions to `v1` implementations.

Old packages default to the Rego v0 syntax, new `v1` packages default to the Rego v1 syntax.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:27:34 +01:00
Johan Fylling 7bb6dbe36b Preparing for v1 API
Moving (most) source to v1 root package to prepare for v0/v1 API separation.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:09:03 +01:00
Johan Fylling acb32722b7 rego-v1: Future-proofing repl pkg tests to be 1.0 compatible (#7026)
Also making some updates to the repl implementation to properly deal with v1 as the default rego-version.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-09-19 11:13:15 +02:00
Ashutosh Narkar a793f27d1f repl: Add support for correctly loading bundle modules
This change updates the repl so that the modules in the
provided bundle are parsed based on the `rego_version` attribute
in the bundle manifest. Currently that is ignored which leads
to parsing failures.

Fixes: #6872

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2024-07-23 13:31:53 -07:00
Johan Fylling 5464b005e8 Bumping golangci-lint to v1.59.1 (#6817)
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-06-19 15:13:43 +02:00
Johan Fylling b36151d992 Adding --v1-compatible flag to all previously unsupported command line commands (#6521)
In addition to those commands already supported:

* build
* check
* eval
* fmt
* test

support has been added to the following commands:

* `bench`
* `deps`
* `exec`
* `inspect`
* `parse`
* `run` (command `server` and `REPL`)

Fixes: #6520

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-01-24 15:42:32 +01:00
Gianluca Oldani e4c7020a34 repl: only use ToLower on the input command (#5698)
This commit changes the behavior of the function
`newCommand` in `repl.go`. The input of this
function is a string containing both a command
to be run and its arguments. Prior to this commit,
the function converted the entire input to lower
case, without any distinction between the command
and its arguments. This lead to the bug exposed
in issue #5229.
Both the lowercase command and all lower case
arguments are put as fields in the `command`
struct returned by the function.

After this commit, the only part of the string that
is converted to lower case is the command that is
being executed, while the provided arguments are
evaluated as provided to the function. The struct
returned now contains the lower
case command and the arguments as provided to the
function.

Fixes: #5229

Signed-off-by: Gianluca Oldani <oldanigianluca@gmail.com>
2023-02-27 13:04:35 +01:00
Anders Eknert 50d4e31d6b chore: Use t.Setenv in tests (#5321)
And enable the `tenv` linter for the future.

Also, bump version of golangci-lint and fix some new
warnings that came from that.

Signed-off-by: Anders Eknert <anders@eknert.com>
2022-10-27 17:44:56 +02:00
Anders Eknert 9a597feb2e chore: don't use the deprecated ioutil functions (#5319)
Another annoyance removed :P

Signed-off-by: Anders Eknert <anders@eknert.com>
2022-10-27 14:30:26 +02:00
Stephan Renatus 965301f90e ast: support dotted heads (#4660)
This change allows rules to have string prefixes in their heads -- we've
come to call them "ref heads".

String prefixes means that where before, you had

    package a.b.c
    allow = true

you can now have

    package a
    b.c.allow = true

This allows for more concise policies, and different ways to structure
larger rule corpuses.

Backwards-compatibility:

- There are code paths that accept ast.Module structs that don't necessarily
  come from the parser -- so we're backfilling the rule's Head.Reference
  field from the Name when it's not present.
  This is exposed through (Head).Ref() which always returns a Ref.

  This also affects the `opa parse` "pretty" output:

  With x.rego as

    package x
    import future.keywords
    a.b.c.d if true
    e[x] if true

  we get

    $ opa parse x rego
    module
     package
      ref
       data
       "x"
     import
      ref
       future
       "keywords"

     rule
      head
       ref
        a
        "b"
        "c"
        "d"
       true
      body
       expr index=0
        true
     rule
      head
       ref
        e
        x
       true
      body
       expr index=0
        true

  Note that

    Name: e
    Key: x

  becomes

    Reference: e[x]

  in the output above (since that's how we're parsing it, back-compat edge cases aside)

- One special case for backcompat is `p[x] { ... }`:

    rule                    | ref   | key | value | name
    ------------------------+-------+-----+-------+-----
    p[x] { ... }            | p     | x   | nil   | "p"
    p contains x if { ... } | p     | x   | nil   | "p"
    p[x] if { ... }         | p[x]  | nil | true  | ""

  For interpreting a rule, we now have the following procedure:

  1. if it has a Key, it's a multi-value rule; and its Ref defines the set:

     Head{Key: x, Ref: p} ~> p is a set
     ^-- we'd get this from `p contains x if true`
         or `p[x] { true }` (back compat)

  2. if it has a Value, it's a single-value rule; its Ref may contain vars:

     Head{Ref: p.q.r[s], Value: 12} ~> body determines s, `p.q.r.[s]` is 12
     ^-- we'd get this from `p.q.r[s] = 12 { s := "whatever" }`

     Head{Key: x, Ref: p[x], Value: 3} ~> `p[x]` has value 3, `x` is determined
                                          by the rule body
     ^-- we'd get this from `p[x] = 3 if x := 2`
         or `p[x] = 3 { x := 2 }` (back compat)

     Here, the Key isn't used, it's present for backwards compatibility: for ref-
     less rule heads, `p[x] = 3` used to be a partial object: key x, value 3,
     name "p"

- The destinction between complete rules and partial object rules disappears.
  They're both single-value rules now.

- We're now outputting the refs of the rules completely in error messages, as
  it's hard to make sense of "rule r" when there's rule r in package a.b.c and
  rule b.c.r in package a.

Restrictions/next steps:

- Support for ref head rules in the REPL is pretty poor so far. Anything that
  works does so rather accidentally. You should be able to work with policies
  that contain ref heads, but you cannot interactively define them.
  
  This is because before, we'd looked at REPL input like

      p.foo.bar = true

  and noticed that it cannot be a rule, so it's got to be a query. This is no
  longer the case with ref heads.

- Currently vars in Refs are only allowed in the last position. This is expected
 to change in the future.

- Also, for multi-value rules, we can not have a var at all -- so the following
  isn't supported yet:

      p.q.r[s] contains t if { ... }

-----

Most of the work happens when the RuleTree is derived from the ModuleTree -- in
the RuleTree, it doesn't matter if a rule was `p` in `package a.b.c` or `b.c.p`
in `package a`.

As such, the planner and wasm compiler hasn't seen that many adaptations:

- We're putting rules into the ruletree _including_ the var parts, so

  p.q.a = 1
  p.q.[x] = 2 { x := "b" }

  end up in two different leaves:

  p
  `-> q
       `-> a = 1
       `-> [x] = 2`

- When planing a ref, we're checking if a rule tree node's children have
  var keys, and plan "one level higher" accordingly:

  Both sets of rules, p.q.a and p.q[x] will be planned into one function
  (same as before); and accordingly return an object {"a": 1, "b": 2}

- When we don't have vars in the last ref part, we'll end up planning
  the rules separately. This will have an effect on the IR.

  p.q = 1
  p.r = 2

  Before, these would have been one function; now, it's two. As a result,
  in Wasm, some "object insertion" conflicts can become "var assignment
  conflicts", but that's in line with the now-new view of "multi-value"
  and "single-value" rules, not partial {set/obj} vs complete.
* planner: only check ref.GroundPrefix() for optimizations

In a previous commit, we've only mapped

    p.q.r[7]

as p.q.r;  and as such, also need to lookup the ref

    p.q.r[__local0__]

via p.q.r

(I think. Full disclosure: there might be edge cases here that are unaccounted
for, but right now, I'm aiming for making the existing tests green...)


New compiler stage:

In the compiler, we're having a new early rewriting step to ensure that the
RuleTree's keys are comparible. They're ast.Value, but some of them cause us
grief:

- ast.Object cannot be compared structurally; so

      _, ok := map[ast.Value]bool{ast.NewObject([2]*ast.Term{ast.StringTerm("foo"), ast.StringTerm("bar")}): true}[ast.NewObject([2]*ast.Term{ast.StringTerm("foo"), ast.StringTerm("bar")})]

  `ok` will never be true here.

- ast.Ref is a slice type, not hashable, so adding that to the RuleTree would
  cause a runtime panic:

      p[y.z] { y := input }

  is now rewritten to

    p[__local0__] { y := input; __local0__ := y.z }

This required moving the InitLocalVarGen stage up the chain, but as it's still
below ResolveRefs, we should be OK.

As a consequence, we've had to adapt `oracle` to cope with that rewriting:

1. The compiler rewrites rule head refs early because the rule tree expects
   only simple vars, no refs, in rule head refs. So `p[x.y]` becomes
   `p[local] { local = x.y }`
2. The oracle circles in on the node it's finding the definition for based
   on source location, and the logic for doing that depends on unaltered
   modules.

So here, (2.) is relaxed: the logic for building the lookup node stack can
now cope with generated statements that have been appended to the rule bodies.


There is a peculiarity about ref rules and extents:

See the added tests: having a ref rule implies that we get an empty object
in the full extent:

    package p
    foo.bar if false

makes the extent of data.p: {"foo": {}}

This is somewhat odd, but also follows from the behaviour we have right now
with empty modules:

    package p.foo
    bar if false

this also gives data.p the extent {"foo": {}}.

This could be worked around by recording, in the rule tree, when a node was
added because it's an intermediary with no values, but only children.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-10-14 10:15:54 +02:00
Eng Zer Jun 97f36e89ef test: use T.TempDir to create temporary test directory (#5227)
This commit replaces `os.MkdirTemp` with `t.TempDir` in tests. The
directory created by `t.TempDir` is automatically removed when the test
and all its subtests complete.

Prior to this commit, temporary directory created using `os.MkdirTemp`
needs to be removed manually by calling `os.RemoveAll`, which is omitted
in some tests. The error handling boilerplate e.g.
	defer func() {
		if err := os.RemoveAll(dir); err != nil {
			t.Fatal(err)
		}
	}
is also tedious, but `t.TempDir` handles this for us nicely.

Reference: https://pkg.go.dev/testing#T.TempDir

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2022-10-11 09:31:38 +02:00
Jasper Van der Jeugt a56c231269 feature: add UnifyOp to tracer events (#5203)
This would be useful for us for two immediate use cases:

1.  Show how and why rules failed in more detail in verbose tooling,
    we can show the unification happening step by step.
2.  We can trace which parts of the input document were used, if we
    add `Location` info those terms.

However, I think it's generally useful for debugging tools.

This increases verbosity in the explain logs, so we decided to add a new explain
mode `debug` in addition to the existing `full`, `notes`, `fails`, `off` modes.
This can be set using the `--explain=debug` flag on the CLI, or by using `trace
debug` in the REPL.

Signed-off-by: Jasper Van der Jeugt <m@jaspervdj.be>
2022-10-10 11:57:31 +02:00
Stephan Renatus 137d7b6f72 storage/inmem: Allow disabling util.Roundtrip on Write (#5015)
Add option to inmem.store which allows disabling the round-tripping
through JSON when adding data to the store.

This option is intended for callers who can guarantee the objects they
pass to Write are JSON objects, and have properly ensured the object
will be only be accessed by store once added.

Fixes #4708.

This is continuance of https://github.com/open-policy-agent/opa/pull/4709,
adding these bits:

* storage/inmem: backwards-compat nitpicks, test adaptations

  I might have overshot here, but adding variable-length function parameters
  is not a backwards-compatible move. Concretely, if you had been using code like

      var x func() storage.Store = inmem.New

  going from New() to New(...Opts) would break it.

* storage/inmem: use it where possible without roundtrip

* storage/inmem: deal with nil map

  It looks like this is something the roundtrip had guarded us from.
  Now, we'll explicitly check this.

  This came up when running the bundle tests with roundtripping disabled.

* loader: add StoreWithOpts convenience method

Co-authored-by: Will Beason <willbeason@google.com>
Co-authored-by: Philip Conrad <conradp@chariot-chaser.net>
Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-08-18 08:38:21 +02:00
Jasper Van der Jeugt 5ff2231148 repl: Add a WithCapabilities function (#4816)
We are wrapping REPL and this allows us to remove some builtins.

Signed-off-by: Jasper Van der Jeugt <m@jaspervdj.be>
2022-06-28 10:28:56 +02:00
Stephan Renatus c97f58be98 ast/compile: check arity in undefined function stage (#4059)
* ast/compile: check arity in undefined function stage

Before, the "undefined function" check stage in the compiler (and query
compiler) only asserted that the function was known.

Now, we'll also check that the number of arguments _could be_ valid. If
it really is valid will be determined by the type checker at a later
stage.

However, asserting the arity early allows us to give more on-the-spot
error messages.

Fixes #4054.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-12-01 09:56:52 +01:00
Stephan Renatus 2f6bf3f12b ast+topdown: exit-early for (constant) complete virtual docs and functions (#3898)
If the following conditions hold for a set of rules returned by the indexer,
it will set EarlyExit: true, and change how the complete virtual doc or
function is evaluated:

- all rule head values are ground
- all rule head values match

This implies that some cases where early exit would be possible will not be
covered:

    p = x {
      x := true
      input.foo == "bar"
    }

    p = x {
      x := true
      input.baz == "quz"
    }

To indicate that "early exit" is possible, the indexer result message is
amended. Also, the "Exit" trace event will have a message of "early" when
"early exit" actually happens in eval:

    $ echo '{"x":"x", "y":"y"}' | opa eval -I -fpretty --explain=full -d r.rego data.r.r
    query:1       Enter data.r.r = _
    query:1       | Eval data.r.r = _
    query:1       | Index data.r.r (matched 2 rules, early exit)
    r.rego:11     | Enter data.r.r
    r.rego:12     | | Eval input.y = "y"
    r.rego:11     | | Exit data.r.r
    query:1       | Exit data.r.r = _
    query:1       Redo data.r.r = _
    query:1       | Redo data.r.r = _
    r.rego:11     | Redo data.r.r
    r.rego:12     | | Redo input.y = "y"
    r.rego:11     | Exit data.r.r early

With `r.rego` as

    package r
    r {
      input.x = "x"
    }
    r = 2 {
      input.z = "z"
    }
    r {
      input.y = "y"
    }

This is done in in a way such that early-exit will abort array/set/object
iterations on data:

    r {
      data.i[_] = "one"
      data.j[_] = "four"
    }

    f(x, y) {
      data.i[_] = x
      data.j[_] = y
    }

Complete rules (r) and functions (f) that iterate over sets, arrays, and
objects from either data (evalTree) or a term that's returned by some
other rule etc (evalTerm).

The CLI and golang packages expose ways to disable 'early-exit':

This is in line with how indexing can be disabled. It's supposed to be
used as a debugging measure, so it's only exposed as a CLI flag to
`opa eval`.

Co-authored-by: Torin Sandall <torinsandall@gmail.com>
Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-11-18 10:49:09 +01:00
Stephan Renatus 53c5a871d0 repl: expose future.keywords import feature
The future.keywords import can be accessed via the repl in the same
way any other import can, and is handled accordingly:

    > show
    no rules defined
    > import future.keywords.in
    > show
    package repl

    import future.keywords.in
    > 1 in [true]
    false
    > r { input in data.foo }
    Rule 'r' defined in package repl. Type 'show' to see rules.
    > show
    package repl

    import future.keywords.in

    r {
            input in data.foo
    }
    >

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-10-14 19:21:52 +02:00
Torin Sandall f6146f01b3 repl: Enable print calls
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-10-14 09:31:16 -07:00
Stephan Renatus 6e4377af59 rego: make wasmtime-go dependency "more optional" (#3708)
Users of OPA as a library are concerned about big binary blobs in their vendor/
directories. Even more so if they don't use them. This is the case for anyone
using OPA as library, but not using the wasm-backed evaluation feature.

With this change, importers of any packages other than `server` and `cmd`
will have to explicitly opt-in to using wasm evaluation features by having an
underscore import somewhere:

    import _ "github.com/open-policy-agent/opa/features/wasm"

Fixes #3545.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-08-16 11:48:43 +02:00
Will Beason 3be1d08b87 Change check-lint to use golangci-lint (#3465)
golint is deprecated. The author of the code no longer supports the
codebase. golangci-lint is faster than golint, and is in use by other
opa repositories (e.g. Gatekeeper).

This commit changes tools.go to reference golangci (so it ends up in
vendor) and modifies check-lint to use golangci instead.

Breaking API Changes:

- plugins/rest/rest.go: Fix typo "AllowInsureTLS" -> "AllowInsecureTLS"
- storage/errors.go: Removed unused IndexingNotSupportedErr

Signed-off-by: Will Beason <willbeason@google.com>
2021-05-19 07:52:02 +02:00
Stephan Renatus dc820b5d82 tests: fix wasm tests
xyz_wasm_test.go makes go implicitly require the GOOS to be wasm.
That's not what we want here.

Example go test list before:

    $ go test --tags=opa_wasm ./repl -list TestReplWasmTarget
    ok      github.com/open-policy-agent/opa/repl   0.006s

After:

    $ go test --tags=opa_wasm ./repl -list TestReplWasmTarget
    TestReplWasmTarget
    ok      github.com/open-policy-agent/opa/repl   0.007s

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-03-03 09:32:11 -05:00
Anders Eknert b02db2e98a Skip WASM tests on WASM_ENABLED=0
Signed-off-by: Anders Eknert <anders@eknert.com>
2021-02-24 13:24:15 +01:00
Ashutosh Narkar 2b2d73ebbf Add target flag to OPA subcommands
This commit adds a target flag to the
bench, eval, test and run (repl) commands
which allows users to exercise the wasm
rumtime.

Fixes #2878

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2021-02-05 10:16:22 -08:00
Stephan Renatus ccac1370c4 Fix const types in internal/jwx/jwk/key_ops.go and repl/repl.go (#3021)
This was flagged by staticcheck, reported in #3020.

See also https://staticcheck.io/docs/checks#SA9004

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2020-12-18 15:39:29 +01:00
Torin Sandall 2dbc0f556e repl: Add strict-builtin-errors command
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-10-23 12:28:23 -07:00
Patrick East b45ab28375 rego: Plumb the newer QueryTracer through Rego API's
This will deprecate the older API's that used the `topdown.Tracer` in
favor of the newer `topdown.QueryTracer` interface. Usages of the old
API have been swapped, although some of the testing is left with them
to ensure we still support them (until we remove the deprecated API).

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-15 12:01:12 -07:00
Ashutosh Narkar 458a61aa28 Add anonymous version reporting feature to OPA
This commit updates the OPA `run` and `version` commands to report the
version of the running OPA instance to an external service.

In case of the `opa run` command, this feature is ON by-default and
can be disabled using the --skip-version-check flag. In the server mode,
reports are sent periodically while in repl mode only once at start-up.

In case of the opa version command, this feature can be enabled by
specifying the --check or -c flag.

Reports are sent to the configurable external service
on a best-effort basis.

Fixes #1253

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2020-05-20 16:41:52 -07:00
timakin 7df620c6ee Fixes 2338
Signed-off-by: timakin <timaki.st@gmail.com>

through if at least one of expressions has a non-boolean value

Signed-off-by: timakin <timaki.st@gmail.com>

defined boolRenderable func which checks boolean Values and Bindings contents

Signed-off-by: timakin <timaki.st@gmail.com>

added a test for boolean flags pretty printing

Signed-off-by: timakin <timaki.st@gmail.com>

add a newline at end of file

Signed-off-by: timakin <timaki.st@gmail.com>

adda  newline at end of file

Signed-off-by: timakin <timaki.st@gmail.com>

use len(rs[0].Bindings) to simplify functions

Signed-off-by: timakin <timaki.st@gmail.com>

simplified selectVarValue

Signed-off-by: timakin <timaki.st@gmail.com>

delete unused the existence flag of selectVarValue result

Signed-off-by: timakin <timaki.st@gmail.com>

delete an empty line

Signed-off-by: timakin <timaki.st@gmail.com>

delete an empty line

Signed-off-by: timakin <timaki.st@gmail.com>
2020-05-18 07:35:09 -04:00
Torin Sandall 23e2a51fbc topdown: Fix trace to set location on notes
Previously the note events would not have a location on them which
mean they were difficult to track down (you would have to grep for the
message and hope it shows up.) With this change we just include the
location on notes like all other events.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-04-17 06:51:28 -04:00
Patrick East 94cd44ed4e topdown: Improve pretty trace location details
Previously we had a hard set width for location info in pretty trace
outputs. This changes to use a dynamic width up to a reasonable max
and then starts to shorten paths as possible by swapping in `...` for
the longest common substring of all paths.

To get the longest substring this brings in a couple files from
https://github.com/vmarkovtsev/go-lcss which implements an efficient
algorithm for it (rather than us implementing something fancy from
scratch). It's pretty isolated and is unlikely to need any updates
over time so the maintenance should be low.

Fixes: #2143
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-04-02 11:10:13 -07:00
Frederic c01ea9062f Add unset-package command to REPL
This command is useful for removing packages from
the current REPL session without having to exit it

Fixes #2140

Signed-off-by: Frederic <frederic.vanreet@icloud.com>
2020-03-30 11:30:37 -07:00
Lennard Eijsackers 825ae01c2d Add location information into pretty printed trace output.
Fixes #2070

Signed-off-by: Lennard Eijsackers <lennardeijsackers92@gmail.com>
2020-02-11 12:01:28 -08:00
Teemu Koponen c44f3d714c ast: Generic/BeforeAfter/Var Visitor specific Walk implementations.
Unlike the generic Walk implementations, they don't necessitate
allocating the visitor itself from heap.

This deprecates ast.Visitor, ast.BeforeAndAfterVisitor, ast.Walk, and
ast.WalkBeforeAndAfter.

Benchmarks changed:

name                                  old time/op    new time/op    delta
PartialEval/1-16                        6.41µs ± 1%    6.35µs ± 1%   -1.01%  (p=0.001 n=10+10)
PartialEval/10-16                       6.47µs ± 1%    6.37µs ± 1%   -1.48%  (p=0.000 n=10+10)
PartialEval/100-16                      6.81µs ± 1%    6.78µs ± 1%   -0.44%  (p=0.041 n=9+10)
PartialEval/1000-16                     6.64µs ± 2%    6.57µs ± 2%   -1.02%  (p=0.037 n=10+10)
PartialEvalCompile/1-16                 3.08ms ± 0%    2.99ms ± 0%   -2.73%  (p=0.000 n=8+9)
PartialEvalCompile/10-16                4.17ms ± 0%    3.97ms ± 1%   -4.67%  (p=0.000 n=9+9)
PartialEvalCompile/100-16               25.1ms ± 1%    22.9ms ± 1%   -8.67%  (p=0.000 n=9+10)
PartialEvalCompile/1000-16               1.27s ± 2%     1.20s ± 1%   -5.37%  (p=0.000 n=10+9)
InliningFullScan/1000-16                5.24ms ± 1%    4.83ms ± 1%   -7.75%  (p=0.000 n=10+10)
InliningFullScan/10000-16               55.0ms ± 0%    51.0ms ± 1%   -7.25%  (p=0.000 n=9+10)
InliningFullScan/300000-16               1.59s ± 1%     1.48s ± 1%   -6.63%  (p=0.000 n=9+9)

name                                  old alloc/op   new alloc/op   delta
Concurrency1-16                          100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=10+10)
Concurrency2-16                          100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=10+10)
Concurrency4-16                          100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=9+10)
Concurrency8-16                          100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=10+10)
Concurrency4Readers1Writer-16            100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=10+10)
Concurrency8Writers-16                   100MB ± 0%     100MB ± 0%   -0.05%  (p=0.000 n=10+10)
PartialEvalCompile/1-16                 1.31MB ± 0%    1.29MB ± 0%   -1.10%  (p=0.000 n=8+9)
PartialEvalCompile/10-16                1.74MB ± 0%    1.70MB ± 0%   -2.42%  (p=0.000 n=9+10)
PartialEvalCompile/100-16               8.90MB ± 0%    8.58MB ± 0%   -3.58%  (p=0.000 n=10+9)
PartialEvalCompile/1000-16               370MB ± 0%     366MB ± 0%   -0.84%  (p=0.000 n=9+9)
Walk/100-16                              361kB ± 0%     360kB ± 0%   -0.32%  (p=0.000 n=10+10)
Walk/1000-16                             413kB ± 0%     412kB ± 0%   -0.28%  (p=0.000 n=10+10)
Walk/2000-16                             471kB ± 0%     470kB ± 0%   -0.24%  (p=0.000 n=10+10)
Walk/3000-16                             527kB ± 0%     526kB ± 0%   -0.22%  (p=0.000 n=9+10)
InliningFullScan/1000-16                2.77MB ± 0%    2.68MB ± 0%   -3.18%  (p=0.000 n=9+10)
InliningFullScan/10000-16               28.2MB ± 0%    27.4MB ± 0%   -3.12%  (p=0.000 n=10+10)
InliningFullScan/300000-16               852MB ± 0%     825MB ± 0%   -3.10%  (p=0.000 n=10+9)

Signed-off-by: Teemu Koponen <koponen@styra.com>
2020-01-22 18:32:54 -05:00
Patrick East f1b9c7586b Ensure all errors are in JSON formatted CLI output
Previously if the errors passed into the presentation Output were not
structured w/ JSON tags for marshaling the error would be an empty
string.

This changes to wrap the errors with a struct in cases where they
would otherwise not be formatted. We do this by forcing every error
into a structure and translating known error types into it.

Fixes: #1726
Fixes: #1724
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-09-27 10:55:31 -04:00
Patrick East b48c534722 Run make fmt with new goimports cmd
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-09-27 09:55:11 -04:00
Torin Sandall 6b4dbb3c66 repl: Fix unknown argument processing
The REPL's internal state was getting corrupted if an invalid unknown
term was given. For example `unknown x-1` would result in the unknown
set being allocated but it would contain an illegal nil element.

This fix just updates the REPL to avoid corrupting the internal state
if any of the unknown arguments are invalid.

Fixes #1670

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-09-17 19:05:15 -04:00
ethan 692a80c01b repl.go: command help message correction
repl.go: wording flag message to make it more understandable

Signed-off-by: Guangming Wang <guangming.wang@daocloud.io>
2019-08-13 13:43:00 -04:00
Torin Sandall a6e6e2d660 repl: Fix regression in interpreting statements as rules
While adding support for the some keyword in the REPL and fixing #1104
there was a regression where statements like `input = 1` would always
be interpreted as rules. We made a decision a long time ago that the
first time an expression like `input = 1` was encountered that a rule
would be declared but that subsequent similar expressions (e.g., input
= 1 or input = {"foo":"bar"} or ...) would perform a comparison. The
regression broke this for cases where the left hand side was a
reference to a global document (i.e., input or data). This commit just
fixes the regression by updating the global check to account for refs.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-08-07 14:22:45 -04:00
Torin Sandall 54c21b7c0b repl: Update to use helper to construct rule from := expression
This avoids duplicating any logic that may be required to construct
rules from := expressions. Currently the only extra bit of logic is to
set the assignment flag on the rule head. This change lets us
determine whether the rules are unset in the REPL in a more
declarative manner (i.e., if it's an assignment rule then it will
unset in all cases) and ensure that the assignment operator is not
lost in the show command output.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-08-07 14:22:45 -04:00
Torin Sandall e37482d9cd repl: Update REPL to support fails explanation mode
Also, refactor how the REPL prints debug state a bit to reduce
boilerplate for each possible explanation mode.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-07-29 18:56:09 -04:00
Torin Sandall 3263f54a74 ast: Rename 'var' to 'some'
This commit renames the 'var' keyword to 'some'. 'some' is more
descriptive than 'var' and will better complement an 'every' or
'forall' keyword representing for universal quantifiers.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-05-18 21:27:32 -07:00
Torin Sandall 164d1a0abb ast: Update REPL to handle var keyword
In the process this addresses an issue where nested expressions are
not assigned.

Fixes #1104

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-05-18 21:27:32 -07:00
Torin Sandall 89fc02a135 repl: Update REPL to support notes explanation mode
Also fix show debug test and remove dead trace mangling code.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-05-10 10:33:40 -07:00
Patrick East d07b6b3723 Add additional compiler metrics for each stage
Each stage of the compiler now has its own timer when instrumentation
is enabled.

To keep things consistent the naming follows the lowercase and
underscore style that the existing ones have. Each stage now needs
to define not only its name but its metric name too.

This does make a change to the ast compiler API by requiring the
additional naming information when adding extra stages.

And example of the new metrics:

```
+----------------------------------------------------------+--------------------+
|                          METRIC                          |       VALUE        |
+----------------------------------------------------------+--------------------+
| counter_eval_op_virtual_cache_miss                       | 1                  |
| histogram_eval_op_plug_75%                               | 881                |

<snip>

| histogram_eval_op_rule_index_min                         | 12995              |
| histogram_eval_op_rule_index_stddev                      | 0                  |
| timer_compile_stage_check_recursion_ns                   | 3080               |
| timer_compile_stage_check_rule_conflicts_ns              | 3141               |
| timer_compile_stage_check_safety_rule_bodies_ns          | 26366              |
| timer_compile_stage_check_safety_rule_heads_ns           | 10365              |
| timer_compile_stage_check_types_ns                       | 13269              |
| timer_compile_stage_rebuild_indices_ns                   | 13742              |
| timer_compile_stage_resolve_refs_ns                      | 20219              |
| timer_compile_stage_rewrite_assignments_ns               | 27630              |
| timer_compile_stage_rewrite_comprehension_terms_ns       | 10804              |
| timer_compile_stage_rewrite_dynamic_terms_ns             | 12036              |
| timer_compile_stage_rewrite_equals_ns                    | 7569               |
| timer_compile_stage_rewrite_expr_terms_ns                | 14067              |
| timer_compile_stage_rewrite_refs_in_head_ns              | 25290              |
| timer_compile_stage_rewrite_with_values_ns               | 9931               |
| timer_compile_stage_set_graph_ns                         | 11567              |
| timer_compile_stage_set_module_tree_ns                   | 3739               |
| timer_compile_stage_set_rule_tree_ns                     | 3093               |
| timer_eval_op_plug_ns                                    | 3203               |
| timer_eval_op_rule_index_ns                              | 12995              |
| timer_query_compile_stage_check_safety_ns                | 60071              |
| timer_query_compile_stage_check_types_ns                 | 55424              |
| timer_query_compile_stage_resolve_refs_ns                | 20801              |
| timer_query_compile_stage_rewrite_assignments_ns         | 20198              |
| timer_query_compile_stage_rewrite_comprehension_terms_ns | 10297              |
| timer_query_compile_stage_rewrite_dynamic_terms_ns       | 10086              |
| timer_query_compile_stage_rewrite_expr_terms_ns          | 9161               |
| timer_query_compile_stage_rewrite_to_capture_value_ns    | 21270              |
| timer_query_compile_stage_rewrite_with_values_ns         | 7114               |
| timer_rego_input_parse_ns                                | 575                |
| timer_rego_module_compile_ns                             | 423224             |
| timer_rego_module_parse_ns                               | 481                |
| timer_rego_query_compile_ns                              | 237144             |
| timer_rego_query_eval_ns                                 | 149115             |
| timer_rego_query_parse_ns                                | 344023             |
+----------------------------------------------------------+--------------------+
```

Fixes: #1059

Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-05-08 09:41:38 -07:00
Patrick East dea3b489b4 Decouple Rego input and query options
The process to decouple the input and query compilation had already been
started. Aside from custom compilation stages which might live out of the tree
there are no usages of the input in the current QueryCompiler implementation,
all had been removed previously. This change removes the connection between
the two and more formally breaks the two apart.

The benefit here is that we can compile and cache queries independent from
the input.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-04-23 22:38:04 -07:00
Torin Sandall 001b0fa196 repl: Make REPL module instantiation lazy
Previously the REPL would initialize with a 'repl' package that
contained a rule with the build version in it. Now that the build
version is stored in data and we don't have the rule, the 'repl'
package is empty on startup. This is a bit ugly since running a query
like 'data' displays {"repl": {}}.

With these changes the default REPL module is instantiated
lazily. This means that when users type 'data' upon entering the REPL
they see a nice clean empty object.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-02-22 14:55:36 -08:00
Torin Sandall e2ac20284c runtime: Refactor build version information
Previously the build version was recorded in the version package and
then different components would report it in an ad-hoc manner, e.g.,
the REPL has a module that generates a virtual doc with the version
info in it, the server was using templating to do the same, etc.

These changes remove the special code from the REPL and server
implementations to report the version. Instead the runtime writes the
version into /system/version at boot.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-02-22 14:55:36 -08:00
Torin Sandall a03aa70b38 Fix REPL to check number of assignment operands
This was causing a panic because the AST helper to convert the
expression into a rule was (rightly) assuming the operands would be
non-nil. The REPL should just ignore the expression if it's not
well-formed.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2018-11-23 09:56:24 -08:00