@@ -31,23 +31,35 @@ func parsePath(sqlPath string, inPkg string, s *Schema, settings dinosql.Generat
31
31
return nil , err
32
32
}
33
33
34
+ parseErrors := dinosql.ParserErr {}
35
+
34
36
parsedQueries := []* Query {}
35
37
for _ , filename := range files {
36
38
blob , err := ioutil .ReadFile (filename )
37
39
if err != nil {
38
- return nil , fmt . Errorf ( "Failed to read file [%v]: %w" , filename , err )
40
+ parseErrors . Add ( filename , "" , 0 , err )
39
41
}
40
42
contents := dinosql .RemoveRollbackStatements (string (blob ))
41
43
if err != nil {
42
- return nil , fmt .Errorf ("Failed to read contents of file [%v]: %w" , filename , err )
44
+ parseErrors .Add (filename , "" , 0 , err )
45
+ continue
43
46
}
44
47
queries , err := parseContents (filename , contents , s , settings )
45
48
if err != nil {
46
- return nil , fmt .Errorf ("Failed to parse contents of file [%v]: %w" , filename , err )
49
+ if positionedErr , ok := err .(PositionedErr ); ok {
50
+ parseErrors .Add (filename , contents , positionedErr .Pos , err )
51
+ } else {
52
+ parseErrors .Add (filename , contents , 0 , err )
53
+ }
54
+ continue
47
55
}
48
56
parsedQueries = append (parsedQueries , queries ... )
49
57
}
50
58
59
+ if len (parseErrors .Errs ) > 0 {
60
+ return nil , & parseErrors
61
+ }
62
+
51
63
return & Result {
52
64
Queries : parsedQueries ,
53
65
Schema : s ,
@@ -64,12 +76,20 @@ func parseContents(filename, contents string, s *Schema, settings dinosql.Genera
64
76
if err == io .EOF {
65
77
break
66
78
} else if err != nil {
67
- return nil , err
79
+ parsedLoc , locErr := locFromSyntaxErr (err )
80
+ if locErr != nil {
81
+ parsedLoc = start // next best guess of the error location
82
+ }
83
+ near , nearErr := nearStrFromSyntaxErr (err )
84
+ if nearErr != nil {
85
+ return nil , PositionedErr {parsedLoc , fmt .Errorf ("syntax error" )}
86
+ }
87
+ return nil , PositionedErr {parsedLoc , fmt .Errorf ("syntax error at or near '%s'" , near )}
68
88
}
69
89
query := contents [start : t .Position - 1 ]
70
90
result , err := parseQueryString (q , query , s , settings )
71
91
if err != nil {
72
- return nil , fmt . Errorf ( "Failed to parse query in filepath [%v]: %w" , filename , err )
92
+ return nil , PositionedErr { start , err }
73
93
}
74
94
start = t .Position
75
95
if result == nil {
@@ -87,26 +107,25 @@ func parseQueryString(tree sqlparser.Statement, query string, s *Schema, setting
87
107
case * sqlparser.Select :
88
108
selectQuery , err := parseSelect (tree , query , s , settings )
89
109
if err != nil {
90
- return nil , fmt . Errorf ( "Failed to parse SELECT query: %w" , err )
110
+ return nil , err
91
111
}
92
112
parsedQuery = selectQuery
93
113
case * sqlparser.Insert :
94
114
insert , err := parseInsert (tree , query , s , settings )
95
115
if err != nil {
96
- return nil , fmt . Errorf ( "Failed to parse INSERT query: %w" , err )
116
+ return nil , err
97
117
}
98
118
parsedQuery = insert
99
119
case * sqlparser.Update :
100
120
update , err := parseUpdate (tree , query , s , settings )
101
121
if err != nil {
102
- return nil , fmt . Errorf ( "Failed to parse UPDATE query: %w" , err )
122
+ return nil , err
103
123
}
104
124
parsedQuery = update
105
125
case * sqlparser.Delete :
106
126
delete , err := parseDelete (tree , query , s , settings )
107
- delete .SchemaLookup = nil
108
127
if err != nil {
109
- return nil , fmt . Errorf ( "Failed to parse DELETE query: %w" , err )
128
+ return nil , err
110
129
}
111
130
parsedQuery = delete
112
131
case * sqlparser.DDL :
@@ -118,28 +137,28 @@ func parseQueryString(tree sqlparser.Statement, query string, s *Schema, setting
118
137
}
119
138
paramsReplacedQuery , err := replaceParamStrs (sqlparser .String (tree ), parsedQuery .Params )
120
139
if err != nil {
121
- return nil , fmt .Errorf ("Failed to replace param variables in query string: %w" , err )
140
+ return nil , fmt .Errorf ("failed to replace param variables in query string: %w" , err )
122
141
}
123
142
parsedQuery .SQL = paramsReplacedQuery
124
143
return parsedQuery , nil
125
144
}
126
145
127
146
func (q * Query ) parseNameAndCmd () error {
128
147
if q == nil {
129
- return fmt .Errorf ("Cannot parse name and cmd from null query" )
148
+ return fmt .Errorf ("cannot parse name and cmd from null query" )
130
149
}
131
150
_ , comments := sqlparser .SplitMarginComments (q .SQL )
132
151
err := q .parseLeadingComment (comments .Leading )
133
152
if err != nil {
134
- return fmt .Errorf ("Failed to parse leading comment %w" , err )
153
+ return fmt .Errorf ("failed to parse leading comment %w" , err )
135
154
}
136
155
return nil
137
156
}
138
157
139
158
func parseSelect (tree * sqlparser.Select , query string , s * Schema , settings dinosql.GenerateSettings ) (* Query , error ) {
140
159
tableAliasMap , err := parseFrom (tree .From , false )
141
160
if err != nil {
142
- return nil , fmt .Errorf ("Failed to parse table name alias's: %w" , err )
161
+ return nil , fmt .Errorf ("failed to parse table name alias's: %w" , err )
143
162
}
144
163
defaultTableName := getDefaultTable (tableAliasMap )
145
164
@@ -205,7 +224,7 @@ func parseFrom(from sqlparser.TableExprs, isLeftJoined bool) (FromTables, error)
205
224
case * sqlparser.AliasedTableExpr :
206
225
name , ok := v .Expr .(sqlparser.TableName )
207
226
if ! ok {
208
- return nil , fmt .Errorf ("Failed to parse AliasedTableExpr name: %v" , spew .Sdump (v ))
227
+ return nil , fmt .Errorf ("failed to parse AliasedTableExpr name: %v" , spew .Sdump (v ))
209
228
}
210
229
t := FromTable {
211
230
TrueName : name .Name .String (),
@@ -232,7 +251,7 @@ func parseFrom(from sqlparser.TableExprs, isLeftJoined bool) (FromTables, error)
232
251
}
233
252
return right , nil
234
253
default :
235
- return nil , fmt .Errorf ("Failed to parse table expr: %v" , spew .Sdump (v ))
254
+ return nil , fmt .Errorf ("failed to parse table expr: %v" , spew .Sdump (v ))
236
255
}
237
256
}
238
257
return tables , nil
@@ -251,7 +270,7 @@ func getDefaultTable(tableAliasMap FromTables) string {
251
270
func parseUpdate (node * sqlparser.Update , query string , s * Schema , settings dinosql.GenerateSettings ) (* Query , error ) {
252
271
tableAliasMap , err := parseFrom (node .TableExprs , false )
253
272
if err != nil {
254
- return nil , fmt .Errorf ("Failed to parse table name alias's: %w" , err )
273
+ return nil , fmt .Errorf ("failed to parse table name alias's: %w" , err )
255
274
}
256
275
defaultTable := getDefaultTable (tableAliasMap )
257
276
if err != nil {
@@ -267,7 +286,7 @@ func parseUpdate(node *sqlparser.Update, query string, s *Schema, settings dinos
267
286
}
268
287
colDfn , err := s .getColType (col , tableAliasMap , defaultTable )
269
288
if err != nil {
270
- return nil , fmt .Errorf ("Failed to determine type of a parameter's column: %w" , err )
289
+ return nil , fmt .Errorf ("failed to determine type of a parameter's column: %w" , err )
271
290
}
272
291
originalParamName := string (newValue .Val )
273
292
param := Param {
@@ -280,7 +299,7 @@ func parseUpdate(node *sqlparser.Update, query string, s *Schema, settings dinos
280
299
281
300
whereParams , err := paramsInWhereExpr (node .Where .Expr , s , tableAliasMap , defaultTable , settings )
282
301
if err != nil {
283
- return nil , fmt .Errorf ("Failed to parse params from WHERE expression: %w" , err )
302
+ return nil , fmt .Errorf ("failed to parse params from WHERE expression: %w" , err )
284
303
}
285
304
286
305
parsedQuery := Query {
@@ -342,7 +361,7 @@ func parseInsert(node *sqlparser.Insert, query string, s *Schema, settings dinos
342
361
func parseDelete (node * sqlparser.Delete , query string , s * Schema , settings dinosql.GenerateSettings ) (* Query , error ) {
343
362
tableAliasMap , err := parseFrom (node .TableExprs , false )
344
363
if err != nil {
345
- return nil , fmt .Errorf ("Failed to parse table name alias's: %w" , err )
364
+ return nil , fmt .Errorf ("failed to parse table name alias's: %w" , err )
346
365
}
347
366
defaultTableName := getDefaultTable (tableAliasMap )
348
367
if err != nil {
@@ -412,7 +431,7 @@ func parseSelectAliasExpr(exprs sqlparser.SelectExprs, s *Schema, tableAliasMap
412
431
case * sqlparser.ColName :
413
432
res , err := s .getColType (v , tableAliasMap , defaultTable )
414
433
if err != nil {
415
- panic ( fmt . Sprintf ( "Column not found in schema: %v" , err ))
434
+ return nil , err
416
435
}
417
436
if hasAlias {
418
437
res .Name = expr .As // applys the alias
@@ -458,11 +477,11 @@ func GeneratePkg(pkgName, schemaPath, querysPath string, settings dinosql.Genera
458
477
s := NewSchema ()
459
478
_ , err := parsePath (schemaPath , pkgName , s , settings )
460
479
if err != nil {
461
- return nil , fmt . Errorf ( "schema failure: %w" , err )
480
+ return nil , err
462
481
}
463
482
result , err := parsePath (querysPath , pkgName , s , settings )
464
483
if err != nil {
465
- return nil , fmt . Errorf ( "query failure: %w" , err )
484
+ return nil , err
466
485
}
467
486
return result , nil
468
487
}
0 commit comments