Skip to content
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
13 changes: 12 additions & 1 deletion book/src/command/super.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Instead, your shell is your REPL and the `super` command lets you:

The `super` command is invoked either by itself to run a query:
```
super [ -c <query> | -I <query-file> ] [ options ] [ <path> ... ]
super [ -c <query> | -I <query-file> ] [ options ] [ <path> ... ] [ -- [ <arg> ... ]]
```
or with a [sub-command](sub-commands.md):
```
Expand All @@ -32,6 +32,17 @@ SuperDB query engine detached from the database storage layer.

The [input data](input.md) may be specified as command-line paths or
referenced within the query.
One or more `<path>` arguments act as if a
[from](../super-sql/operators/from.md) operator has been prepended to
the query specified. When no query is specified,
the inputs are scanned with no query applied.

Arguments may be passed from the command-line into the query using
`--` to terminate the input path specifications and indicate subsequent query arguments.
All of the shell arguments after `--` are assembled into a string array
called `args` as a
[constant](../super-sql/declarations/constants.md)
appearing in the main scope of the query.

For built-in command help and a listing of all available options,
simply run `super` without any arguments.
Expand Down
2 changes: 1 addition & 1 deletion cmd/super/root/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (c *Command) Run(args []string) error {
return nil
}
if len(args) > 0 {
ast.PrependFileScan(args)
args = ast.PrependFileScan(args)
}
env := exec.NewEnvironment(storage.NewLocalEngine(), nil)
env.Dynamic = c.inputFlags.Dynamic
Expand Down
51 changes: 51 additions & 0 deletions cmd/super/ztests/command-args.yaml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Although this tests code in compiler/parser, it's more a test of the super command than the parser itself, so cmd/super/ztests feels like a more natural home.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
script: |
super -s -c "values args" -- a b c

outputs:
- name: stdout
data: |
["a","b","c"]

---

script: |
super -s -c "values args" --

outputs:
- name: stdout
data: |
[]

---

script: |
super -s -c "values args" in.sup --

inputs:
- name: in.sup
data: |
null
null

outputs:
- name: stdout
data: |
[]
[]

---

script: |
super -s -c "values args" - --

inputs:
- name: stdin
data: |
null
null

outputs:
- name: stdout
data: |
[]
[]
9 changes: 4 additions & 5 deletions compiler/ast/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ func (*Decorated) valueNode() {}

type (
Primitive struct {
Kind string `json:"kind" unpack:""`
Type string `json:"type"`
Text string `json:"text"`
TextPos int `json:"text_pos"`
Loc `json:"loc"`
Kind string `json:"kind" unpack:""`
Type string `json:"type"`
Text string `json:"text"`
Loc `json:"loc"`
}
Record struct {
Kind string `json:"kind" unpack:""`
Expand Down
50 changes: 45 additions & 5 deletions compiler/parser/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package parser

import (
"errors"
"slices"

"github.com/brimdata/super/compiler/ast"
"github.com/brimdata/super/compiler/srcfiles"
Expand Down Expand Up @@ -36,11 +37,50 @@ func (a *AST) ConvertToDeleteWhere(pool, branch string) error {
return nil
}

func (a *AST) PrependFileScan(paths []string) {
a.seq.Prepend(&ast.FileScan{
Kind: "FileScan",
Paths: paths,
})
func (a *AST) PrependFileScan(paths []string) []string {
var args []string
if k := slices.Index(paths, "--"); k >= 0 {
args = paths[k+1:]
paths = paths[:k]
}
if len(paths) > 0 {
a.seq.Prepend(&ast.FileScan{
Kind: "FileScan",
Paths: paths,
})
}
if args != nil {
a.seq = []ast.Op{
&ast.ScopeOp{
Kind: "ScopeOp",
Decls: []ast.Decl{
&ast.ConstDecl{
Kind: "ConstDecl",
Name: &ast.ID{Name: "args"},
Expr: stringArray(args),
},
},
Body: a.seq,
},
}
}
return paths
}

func stringArray(in []string) ast.Expr {
var elems []ast.ArrayElem
for _, s := range in {
e := &ast.Primitive{
Kind: "Primitive",
Type: "string",
Text: s,
}
elems = append(elems, &ast.ExprElem{Kind: "ExprElem", Expr: e})
}
return &ast.ArrayExpr{
Kind: "ArrayExpr",
Elems: elems,
}
}

// ParseText parses a query text in string form.
Expand Down
14 changes: 12 additions & 2 deletions pkg/charm/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package charm
import (
"flag"
"fmt"
"slices"
"sort"
"strings"
)
Expand Down Expand Up @@ -77,17 +78,26 @@ func parse(spec *Spec, args []string, parent Command, interiorLeaf int) (path, [
}
path = append(path, component)
parent = cmd
// These gymnastics prevent Go flags from stopping at and consuming the "--"
// and retains it as remaining args, which lets us implement args options
// passed to the query with "... -- arg arg"
savedArgs := args
var dashDashArgs []string
if k := slices.Index(args, "--"); k >= 0 {
dashDashArgs = args[k:]
args = args[:k]
}
if err := flags.Parse(args); err != nil {
if usage {
s := strings.Join(args, " ")
s := strings.Join(savedArgs, " ")
err = fmt.Errorf("at flag: %q: %w", s, err)
}
return path, nil, false, err
}
if help {
return path, nil, hidden, NeedHelp
}
rest := flags.Args()
rest := append(flags.Args(), dashDashArgs...)
if len(rest) != 0 {
spec = component.spec.lookupSub(rest[0])
if spec != nil {
Expand Down
Loading