@@ -4,20 +4,18 @@ import (
4
4
"fmt"
5
5
"strings"
6
6
7
- "github.com/sirupsen/logrus"
8
- "github.com/src-d/gitbase"
9
7
bblfsh "gopkg.in/bblfsh/client-go.v2"
10
8
"gopkg.in/bblfsh/client-go.v2/tools"
11
9
"gopkg.in/bblfsh/sdk.v1/uast"
12
10
13
- errors "gopkg.in/src-d/go-errors.v1"
14
11
"gopkg.in/src-d/go-mysql-server.v0/sql"
15
12
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
16
13
)
17
14
18
15
var (
19
- // ErrParseBlob is returned when the blob can't be parsed with bblfsh.
20
- ErrParseBlob = errors .NewKind ("unable to parse the given blob using bblfsh: %s" )
16
+ // UASTExpressionType represents the returned SQL type by
17
+ // the functions uast, uast_mode, uast_xpath and uast_children.
18
+ UASTExpressionType sql.Type = sql .Blob
21
19
)
22
20
23
21
// UAST returns an array of UAST nodes as blobs.
@@ -62,7 +60,7 @@ func (f UAST) Resolved() bool {
62
60
63
61
// Type implements the Expression interface.
64
62
func (f UAST ) Type () sql.Type {
65
- return sql . Array ( sql . Blob )
63
+ return UASTExpressionType
66
64
}
67
65
68
66
// Children implements the Expression interface.
@@ -181,7 +179,7 @@ func (f UASTMode) Resolved() bool {
181
179
182
180
// Type implements the Expression interface.
183
181
func (f UASTMode ) Type () sql.Type {
184
- return sql . Array ( sql . Blob )
182
+ return UASTExpressionType
185
183
}
186
184
187
185
// Children implements the Expression interface.
@@ -290,7 +288,7 @@ func NewUASTXPath(uast, xpath sql.Expression) sql.Expression {
290
288
291
289
// Type implements the Expression interface.
292
290
func (UASTXPath ) Type () sql.Type {
293
- return sql . Array ( sql . Blob )
291
+ return UASTExpressionType
294
292
}
295
293
296
294
// Eval implements the Expression interface.
@@ -309,15 +307,15 @@ func (f *UASTXPath) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err er
309
307
return nil , err
310
308
}
311
309
312
- if left == nil {
313
- return nil , nil
314
- }
315
-
316
- nodes , err := nodesFromBlobArray (left )
310
+ nodes , err := getNodes (ctx , left )
317
311
if err != nil {
318
312
return nil , err
319
313
}
320
314
315
+ if nodes == nil {
316
+ return nil , nil
317
+ }
318
+
321
319
xpath , err := exprToString (ctx , f .Right , row )
322
320
if err != nil {
323
321
return nil , err
@@ -327,58 +325,17 @@ func (f *UASTXPath) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err er
327
325
return nil , nil
328
326
}
329
327
330
- var result []interface {}
328
+ var filtered []* uast. Node
331
329
for _ , n := range nodes {
332
330
ns , err := tools .Filter (n , xpath )
333
331
if err != nil {
334
332
return nil , err
335
333
}
336
334
337
- m , err := marshalNodes (ns )
338
- if err != nil {
339
- return nil , err
340
- }
341
-
342
- result = append (result , m ... )
343
- }
344
-
345
- return result , nil
346
- }
347
-
348
- func nodesFromBlobArray (data interface {}) ([]* uast.Node , error ) {
349
- data , err := sql .Array (sql .Blob ).Convert (data )
350
- if err != nil {
351
- return nil , err
352
- }
353
-
354
- arr := data .([]interface {})
355
- var nodes = make ([]* uast.Node , len (arr ))
356
- for i , n := range arr {
357
- node := uast .NewNode ()
358
- if err := node .Unmarshal (n .([]byte )); err != nil {
359
- return nil , err
360
- }
361
-
362
- nodes [i ] = node
363
- }
364
-
365
- return nodes , nil
366
- }
367
-
368
- func marshalNodes (nodes []* uast.Node ) ([]interface {}, error ) {
369
- m := make ([]interface {}, 0 , len (nodes ))
370
- for _ , n := range nodes {
371
- if n != nil {
372
- data , err := n .Marshal ()
373
- if err != nil {
374
- return nil , err
375
- }
376
-
377
- m = append (m , data )
378
- }
335
+ filtered = append (filtered , ns ... )
379
336
}
380
337
381
- return m , nil
338
+ return marshalNodes ( ctx , filtered )
382
339
}
383
340
384
341
func (f UASTXPath ) String () string {
@@ -400,84 +357,6 @@ func (f UASTXPath) TransformUp(fn sql.TransformExprFunc) (sql.Expression, error)
400
357
return fn (NewUASTXPath (left , right ))
401
358
}
402
359
403
- func exprToString (
404
- ctx * sql.Context ,
405
- e sql.Expression ,
406
- r sql.Row ,
407
- ) (string , error ) {
408
- if e == nil {
409
- return "" , nil
410
- }
411
-
412
- x , err := e .Eval (ctx , r )
413
- if err != nil {
414
- return "" , err
415
- }
416
-
417
- if x == nil {
418
- return "" , nil
419
- }
420
-
421
- x , err = sql .Text .Convert (x )
422
- if err != nil {
423
- return "" , err
424
- }
425
-
426
- return x .(string ), nil
427
- }
428
-
429
- func getUAST (
430
- ctx * sql.Context ,
431
- bytes []byte ,
432
- lang , xpath string ,
433
- mode bblfsh.Mode ,
434
- ) (interface {}, error ) {
435
- session , ok := ctx .Session .(* gitbase.Session )
436
- if ! ok {
437
- return nil , gitbase .ErrInvalidGitbaseSession .New (ctx .Session )
438
- }
439
-
440
- client , err := session .BblfshClient ()
441
- if err != nil {
442
- return nil , err
443
- }
444
-
445
- // If we have a language we must check if it's supported. If we don't, bblfsh
446
- // is the one that will have to identify the language.
447
- if lang != "" {
448
- ok , err = client .IsLanguageSupported (ctx , lang )
449
- if err != nil {
450
- return nil , err
451
- }
452
-
453
- if ! ok {
454
- return nil , nil
455
- }
456
- }
457
-
458
- resp , err := client .ParseWithMode (ctx , mode , lang , bytes )
459
- if err != nil {
460
- logrus .Warn (ErrParseBlob .New (err ))
461
- return nil , nil
462
- }
463
-
464
- if len (resp .Errors ) > 0 {
465
- logrus .Warn (ErrParseBlob .New (strings .Join (resp .Errors , "\n " )))
466
- }
467
-
468
- var nodes []* uast.Node
469
- if xpath == "" {
470
- nodes = []* uast.Node {resp .UAST }
471
- } else {
472
- nodes , err = tools .Filter (resp .UAST , xpath )
473
- if err != nil {
474
- return nil , err
475
- }
476
- }
477
-
478
- return marshalNodes (nodes )
479
- }
480
-
481
360
// UASTExtract extracts keys from an UAST.
482
361
type UASTExtract struct {
483
362
expression.BinaryExpression
@@ -514,15 +393,15 @@ func (u *UASTExtract) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err
514
393
return nil , err
515
394
}
516
395
517
- if left == nil {
518
- return nil , nil
519
- }
520
-
521
- nodes , err := nodesFromBlobArray (left )
396
+ nodes , err := getNodes (ctx , left )
522
397
if err != nil {
523
398
return nil , err
524
399
}
525
400
401
+ if nodes == nil {
402
+ return nil , nil
403
+ }
404
+
526
405
key , err := exprToString (ctx , u .Right , row )
527
406
if err != nil {
528
407
return nil , err
@@ -609,7 +488,7 @@ func (u *UASTChildren) String() string {
609
488
610
489
// Type implements the sql.Expression interface.
611
490
func (u * UASTChildren ) Type () sql.Type {
612
- return sql . Array ( sql . Blob )
491
+ return UASTExpressionType
613
492
}
614
493
615
494
// TransformUp implements the sql.Expression interface.
@@ -638,17 +517,17 @@ func (u *UASTChildren) Eval(ctx *sql.Context, row sql.Row) (out interface{}, err
638
517
return nil , err
639
518
}
640
519
641
- if child == nil {
642
- return nil , nil
643
- }
644
-
645
- nodes , err := nodesFromBlobArray (child )
520
+ nodes , err := getNodes (ctx , child )
646
521
if err != nil {
647
522
return nil , err
648
523
}
649
524
525
+ if nodes == nil {
526
+ return nil , nil
527
+ }
528
+
650
529
children := flattenChildren (nodes )
651
- return marshalNodes (children )
530
+ return marshalNodes (ctx , children )
652
531
}
653
532
654
533
func flattenChildren (nodes []* uast.Node ) []* uast.Node {
0 commit comments