diff --git a/go.mod b/go.mod index 2ac5b0fea3..7e6d0c38b5 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.14 require ( github.com/antlr/antlr4 v0.0.0-20200209180723-1177c0b58d07 + github.com/davecgh/go-spew v1.1.1 github.com/google/go-cmp v0.4.0 github.com/jinzhu/inflection v1.0.0 github.com/lfittl/pg_query_go v1.0.0 diff --git a/internal/cmd/generate.go b/internal/cmd/generate.go index b346e9547f..aaf58aa9e8 100644 --- a/internal/cmd/generate.go +++ b/internal/cmd/generate.go @@ -91,6 +91,12 @@ func Generate(e Env, dir string, stderr io.Writer) (map[string]string, error) { return nil, err } + debug, err := opts.DebugFromEnv() + if err != nil { + fmt.Fprintf(stderr, "error parsing SQLCDEBUG: %s\n", err) + return nil, err + } + output := map[string]string{} errored := false @@ -127,7 +133,9 @@ func Generate(e Env, dir string, stderr io.Writer) (map[string]string, error) { sql.Queries = joined var name string - parseOpts := opts.Parser{} + parseOpts := opts.Parser{ + Debug: debug, + } if sql.Gen.Go != nil { name = combo.Go.Package } else if sql.Gen.Kotlin != nil { diff --git a/internal/compiler/compile.go b/internal/compiler/compile.go index 4a91ac7981..2ac2ed9b96 100644 --- a/internal/compiler/compile.go +++ b/internal/compiler/compile.go @@ -104,7 +104,7 @@ func parseQueries(p Parser, c *catalog.Catalog, queries []string, o opts.Parser) continue } for _, stmt := range stmts { - query, err := parseQuery(p, c, stmt.Raw, src, o.UsePositionalParameters) + query, err := parseQuery(p, c, stmt.Raw, src, o) if err == ErrUnsupportedStatementType { continue } diff --git a/internal/compiler/parse.go b/internal/compiler/parse.go index 21bb1ec56a..6dac33f0b2 100644 --- a/internal/compiler/parse.go +++ b/internal/compiler/parse.go @@ -6,7 +6,9 @@ import ( "sort" "strings" + "github.com/kyleconroy/sqlc/internal/debug" "github.com/kyleconroy/sqlc/internal/metadata" + "github.com/kyleconroy/sqlc/internal/opts" "github.com/kyleconroy/sqlc/internal/source" "github.com/kyleconroy/sqlc/internal/sql/ast" "github.com/kyleconroy/sqlc/internal/sql/ast/pg" @@ -30,7 +32,10 @@ func rewriteNumberedParameters(refs []paramRef, raw *ast.RawStmt, sql string) ([ return edits, nil } -func parseQuery(p Parser, c *catalog.Catalog, stmt ast.Node, src string, rewriteParameters bool) (*Query, error) { +func parseQuery(p Parser, c *catalog.Catalog, stmt ast.Node, src string, o opts.Parser) (*Query, error) { + if o.Debug.DumpAST { + debug.Dump(stmt) + } if err := validate.ParamStyle(stmt); err != nil { return nil, err } @@ -75,7 +80,7 @@ func parseQuery(p Parser, c *catalog.Catalog, stmt ast.Node, src string, rewrite raw, namedParams, edits := rewrite.NamedParameters(raw) rvs := rangeVars(raw.Stmt) refs := findParameters(raw.Stmt) - if rewriteParameters { + if o.UsePositionalParameters { edits, err = rewriteNumberedParameters(refs, raw, rawSQL) if err != nil { return nil, err diff --git a/internal/debug/dump.go b/internal/debug/dump.go new file mode 100644 index 0000000000..512f65c3f7 --- /dev/null +++ b/internal/debug/dump.go @@ -0,0 +1,9 @@ +package debug + +import ( + "github.com/davecgh/go-spew/spew" +) + +func Dump(n interface{}) { + spew.Dump(n) +} diff --git a/internal/opts/debug.go b/internal/opts/debug.go new file mode 100644 index 0000000000..3b66c6ee00 --- /dev/null +++ b/internal/opts/debug.go @@ -0,0 +1,29 @@ +package opts + +import ( + "os" + "strings" +) + +// The SQLCDEBUG variable controls debugging variables within the runtime. It +// is a comma-separated list of name=val pairs setting these named variables: +// +// dumpast: setting dumpast=1 will print the AST of every SQL statement + +type Debug struct { + DumpAST bool +} + +func DebugFromEnv() (Debug, error) { + d := Debug{} + val := os.Getenv("SQLCDEBUG") + if val == "" { + return d, nil + } + for _, pair := range strings.Split(val, ",") { + if pair == "dumpast=1" { + d.DumpAST = true + } + } + return d, nil +} diff --git a/internal/opts/parser.go b/internal/opts/parser.go index d66a82a8bc..7ce464be2c 100644 --- a/internal/opts/parser.go +++ b/internal/opts/parser.go @@ -2,4 +2,5 @@ package opts type Parser struct { UsePositionalParameters bool + Debug Debug }