Skip to content

Commit

Permalink
feat: Parse comment lines starting with @symbol as boolean flags as…
Browse files Browse the repository at this point in the history
…sociated with a query (#2464)
  • Loading branch information
andrewmbenton authored Jul 17, 2023
1 parent d12db53 commit 4d764a2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
9 changes: 8 additions & 1 deletion internal/compiler/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query,
if err := validate.In(c.catalog, raw); err != nil {
return nil, err
}
name, cmd, err := metadata.Parse(strings.TrimSpace(rawSQL), c.parser.CommentSyntax())
name, cmd, err := metadata.ParseQueryNameAndType(strings.TrimSpace(rawSQL), c.parser.CommentSyntax())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -125,11 +125,18 @@ func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query,
if err != nil {
return nil, err
}

flags, err := metadata.ParseQueryFlags(comments)
if err != nil {
return nil, err
}

return &Query{
RawStmt: raw,
Cmd: cmd,
Comments: comments,
Name: name,
Flags: flags,
Params: params,
Columns: cols,
SQL: trimmed,
Expand Down
1 change: 1 addition & 0 deletions internal/compiler/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Query struct {
SQL string
Name string
Cmd string // TODO: Pick a better name. One of: one, many, exec, execrows, copyFrom
Flags map[string]bool
Columns []*Column
Params []Parameter
Comments []string
Expand Down
18 changes: 17 additions & 1 deletion internal/metadata/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func validateQueryName(name string) error {
return nil
}

func Parse(t string, commentStyle CommentSyntax) (string, string, error) {
func ParseQueryNameAndType(t string, commentStyle CommentSyntax) (string, string, error) {
for _, line := range strings.Split(t, "\n") {
var prefix string
if strings.HasPrefix(line, "--") {
Expand Down Expand Up @@ -103,3 +103,19 @@ func Parse(t string, commentStyle CommentSyntax) (string, string, error) {
}
return "", "", nil
}

func ParseQueryFlags(comments []string) (map[string]bool, error) {
flags := make(map[string]bool)
for _, line := range comments {
cleanLine := strings.TrimPrefix(line, "--")
cleanLine = strings.TrimPrefix(cleanLine, "/*")
cleanLine = strings.TrimPrefix(cleanLine, "#")
cleanLine = strings.TrimSuffix(cleanLine, "*/")
cleanLine = strings.TrimSpace(cleanLine)
if strings.HasPrefix(cleanLine, "@") {
flagName := strings.SplitN(cleanLine, " ", 2)[0]
flags[flagName] = true
}
}
return flags, nil
}
26 changes: 22 additions & 4 deletions internal/metadata/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package metadata

import "testing"

func TestParseMetadata(t *testing.T) {
func TestParseQueryNameAndType(t *testing.T) {

for _, query := range []string{
`-- name: CreateFoo, :one`,
Expand All @@ -17,7 +17,7 @@ func TestParseMetadata(t *testing.T) {
"-- name:CreateFoo",
`--name:CreateFoo :two`,
} {
if _, _, err := Parse(query, CommentSyntax{Dash: true}); err == nil {
if _, _, err := ParseQueryNameAndType(query, CommentSyntax{Dash: true}); err == nil {
t.Errorf("expected invalid metadata: %q", query)
}
}
Expand All @@ -27,13 +27,13 @@ func TestParseMetadata(t *testing.T) {
`-- name comment`,
`--name comment`,
} {
if _, _, err := Parse(query, CommentSyntax{Dash: true}); err != nil {
if _, _, err := ParseQueryNameAndType(query, CommentSyntax{Dash: true}); err != nil {
t.Errorf("expected valid comment: %q", query)
}
}

query := `-- name: CreateFoo :one`
queryName, queryType, err := Parse(query, CommentSyntax{Dash: true})
queryName, queryType, err := ParseQueryNameAndType(query, CommentSyntax{Dash: true})
if err != nil {
t.Errorf("expected valid metadata: %q", query)
}
Expand All @@ -45,3 +45,21 @@ func TestParseMetadata(t *testing.T) {
}

}

func TestParseQueryFlags(t *testing.T) {
for _, comments := range [][]string{
{
"-- name: CreateFoo :one",
"-- @flag-foo",
},
} {
flags, err := ParseQueryFlags(comments)
if err != nil {
t.Errorf("expected query flags to parse, got error: %s", err)
}

if !flags["@flag-foo"] {
t.Errorf("expected flag not found")
}
}
}

0 comments on commit 4d764a2

Please sign in to comment.