@@ -14,11 +14,10 @@ import (
1414 "github.com/sqlc-dev/sqlc/internal/sql/ast"
1515)
1616
17- func NewCmdParse () * cobra.Command {
18- cmd := & cobra.Command {
19- Use : "parse [file]" ,
20- Short : "Parse SQL and output the AST as JSON (experimental)" ,
21- Long : `Parse SQL from a file or stdin and output the abstract syntax tree as JSON.
17+ var parseCmd = & cobra.Command {
18+ Use : "parse [file]" ,
19+ Short : "Parse SQL and output the AST as JSON (experimental)" ,
20+ Long : `Parse SQL from a file or stdin and output the abstract syntax tree as JSON.
2221
2322This command is experimental and requires the 'parsecmd' experiment to be enabled.
2423Enable it by setting: SQLCEXPERIMENT=parsecmd
@@ -32,77 +31,72 @@ Examples:
3231
3332 # Parse SQLite SQL
3433 SQLCEXPERIMENT=parsecmd sqlc parse --dialect sqlite queries.sql` ,
35- Args : cobra .MaximumNArgs (1 ),
36- RunE : func (cmd * cobra.Command , args []string ) error {
37- env := ParseEnv (cmd )
38- if ! env .Experiment .ParseCmd {
39- return fmt .Errorf ("parse command requires the 'parsecmd' experiment to be enabled.\n Set SQLCEXPERIMENT=parsecmd to use this command" )
40- }
41-
42- dialect , err := cmd .Flags ().GetString ("dialect" )
34+ Args : cobra .MaximumNArgs (1 ),
35+ RunE : func (cmd * cobra.Command , args []string ) error {
36+ env := ParseEnv (cmd )
37+ if ! env .Experiment .ParseCmd {
38+ return fmt .Errorf ("parse command requires the 'parsecmd' experiment to be enabled.\n Set SQLCEXPERIMENT=parsecmd to use this command" )
39+ }
40+
41+ dialect , err := cmd .Flags ().GetString ("dialect" )
42+ if err != nil {
43+ return err
44+ }
45+ if dialect == "" {
46+ return fmt .Errorf ("--dialect flag is required (postgresql, mysql, or sqlite)" )
47+ }
48+
49+ // Determine input source
50+ var input io.Reader
51+ if len (args ) == 1 {
52+ file , err := os .Open (args [0 ])
4353 if err != nil {
44- return err
45- }
46- if dialect == "" {
47- return fmt .Errorf ("--dialect flag is required (postgresql, mysql, or sqlite)" )
48- }
49-
50- // Determine input source
51- var input io.Reader
52- if len (args ) == 1 {
53- file , err := os .Open (args [0 ])
54- if err != nil {
55- return fmt .Errorf ("failed to open file: %w" , err )
56- }
57- defer file .Close ()
58- input = file
59- } else {
60- // Check if stdin has data
61- stat , err := os .Stdin .Stat ()
62- if err != nil {
63- return fmt .Errorf ("failed to stat stdin: %w" , err )
64- }
65- if (stat .Mode () & os .ModeCharDevice ) != 0 {
66- return fmt .Errorf ("no input provided. Specify a file path or pipe SQL via stdin" )
67- }
68- input = cmd .InOrStdin ()
69- }
70-
71- // Parse SQL based on dialect
72- var stmts []ast.Statement
73- switch dialect {
74- case "postgresql" , "postgres" , "pg" :
75- parser := postgresql .NewParser ()
76- stmts , err = parser .Parse (input )
77- case "mysql" :
78- parser := dolphin .NewParser ()
79- stmts , err = parser .Parse (input )
80- case "sqlite" :
81- parser := sqlite .NewParser ()
82- stmts , err = parser .Parse (input )
83- default :
84- return fmt .Errorf ("unsupported dialect: %s (use postgresql, mysql, or sqlite)" , dialect )
54+ return fmt .Errorf ("failed to open file: %w" , err )
8555 }
56+ defer file .Close ()
57+ input = file
58+ } else {
59+ // Check if stdin has data
60+ stat , err := os .Stdin .Stat ()
8661 if err != nil {
87- return fmt .Errorf ("parse error : %w" , err )
62+ return fmt .Errorf ("failed to stat stdin : %w" , err )
8863 }
89-
90- // Output AST as JSON
91- stdout := cmd .OutOrStdout ()
92- encoder := json .NewEncoder (stdout )
93- encoder .SetIndent ("" , " " )
94-
95- for _ , stmt := range stmts {
96- if err := encoder .Encode (stmt .Raw ); err != nil {
97- return fmt .Errorf ("failed to encode AST: %w" , err )
98- }
64+ if (stat .Mode () & os .ModeCharDevice ) != 0 {
65+ return fmt .Errorf ("no input provided. Specify a file path or pipe SQL via stdin" )
9966 }
67+ input = cmd .InOrStdin ()
68+ }
69+
70+ // Parse SQL based on dialect
71+ var stmts []ast.Statement
72+ switch dialect {
73+ case "postgresql" , "postgres" , "pg" :
74+ parser := postgresql .NewParser ()
75+ stmts , err = parser .Parse (input )
76+ case "mysql" :
77+ parser := dolphin .NewParser ()
78+ stmts , err = parser .Parse (input )
79+ case "sqlite" :
80+ parser := sqlite .NewParser ()
81+ stmts , err = parser .Parse (input )
82+ default :
83+ return fmt .Errorf ("unsupported dialect: %s (use postgresql, mysql, or sqlite)" , dialect )
84+ }
85+ if err != nil {
86+ return fmt .Errorf ("parse error: %w" , err )
87+ }
88+
89+ // Output AST as JSON
90+ stdout := cmd .OutOrStdout ()
91+ encoder := json .NewEncoder (stdout )
92+ encoder .SetIndent ("" , " " )
93+
94+ for _ , stmt := range stmts {
95+ if err := encoder .Encode (stmt .Raw ); err != nil {
96+ return fmt .Errorf ("failed to encode AST: %w" , err )
97+ }
98+ }
10099
101- return nil
102- },
103- }
104-
105- cmd .Flags ().StringP ("dialect" , "d" , "" , "SQL dialect to use (postgresql, mysql, or sqlite)" )
106-
107- return cmd
100+ return nil
101+ },
108102}
0 commit comments