@@ -105,7 +105,7 @@ SelectClause: ast::Projection = {
105
105
Projection: ast::ProjectItem = {
106
106
<expr:ExprQuery>
107
107
=> ast::ProjectItem::ProjectExpr( ast::ProjectExpr{ expr, as_alias: None } ),
108
- <expr:ExprQuery> "AS" <ident:"Identifier"> => {
108
+ <expr:ExprQuery> "AS"? <ident:"Identifier"> => {
109
109
let as_alias = Some( ast::SymbolPrimitive{ value:ident.to_owned()} );
110
110
ast::ProjectItem::ProjectExpr( ast::ProjectExpr{ expr, as_alias } )
111
111
},
@@ -359,68 +359,69 @@ OffsetByClause: Box<ast::Expr> = { "OFFSET" <ExprQuery> }
359
359
// | 4 | ^ | left | exponentiation |
360
360
// | 5 | * / % | left | multiplication, division, modulo |
361
361
// | 6 | + - | left | addition, subtraction |
362
- // | 7 | BETWEEN IN LIKE | | range/set/pattern compare |
363
- // | 8 | < > <= >= | | comparison operators |
364
- // | 9 | = <> != | | equality operators |
365
- // | 10 | IS | | IS [NOT] NULL |
366
- // | 11 | NOT | right | logical negate |
367
- // | 12 | AND | left | logical conjuct |
368
- // | 13 | OR | left | logical disjunct |
362
+ // | 7 | <other> | left | other operators, e.g., `||`
363
+ // | 8 | BETWEEN IN LIKE | | range/set/pattern compare |
364
+ // | 9 | < > <= >= | | comparison operators |
365
+ // | 10 | = <> != | | equality operators |
366
+ // | 11 | IS | | IS [NOT] NULL |
367
+ // | 12 | NOT | right | logical negate |
368
+ // | 13 | AND | left | logical conjuct |
369
+ // | 14 | OR | left | logical disjunct |
369
370
// |-------+-------------------+---------------+------------------------------------|
370
371
//
371
372
// See https://en.wikipedia.org/wiki/Order_of_operations#Programming_languages
372
373
// See https://en.wikipedia.org/wiki/Order_of_operations#Special_cases
373
374
374
375
375
376
pub ExprQuery: Box<ast::Expr> = {
376
- <e:ExprPrecedence13 > => Box::new(e)
377
+ <e:ExprPrecedence14 > => Box::new(e)
377
378
}
378
379
379
- ExprPrecedence13 : ast::Expr = {
380
- <lo:@L> <l:ExprPrecedence13 > "OR" <r:ExprPrecedence12 > <hi:@R> =>
380
+ ExprPrecedence14 : ast::Expr = {
381
+ <lo:@L> <l:ExprPrecedence14 > "OR" <r:ExprPrecedence13 > <hi:@R> =>
381
382
ast::Expr{ kind: ast::ExprKind::BinOp(
382
383
ast::BinOp {
383
384
kind: ast::BinOpKind::Or,
384
385
lhs: Box::new(l),
385
386
rhs: Box::new(r),
386
387
}.ast(lo..hi)
387
388
)},
388
- <ExprPrecedence12 >,
389
+ <ExprPrecedence13 >,
389
390
}
390
391
391
- ExprPrecedence12 : ast::Expr = {
392
- <lo:@L> <l:ExprPrecedence12 > "AND" <r:ExprPrecedence11 > <hi:@R> =>
392
+ ExprPrecedence13 : ast::Expr = {
393
+ <lo:@L> <l:ExprPrecedence13 > "AND" <r:ExprPrecedence12 > <hi:@R> =>
393
394
ast::Expr{ kind: ast::ExprKind::BinOp(
394
395
ast::BinOp {
395
396
kind: ast::BinOpKind::And,
396
397
lhs: Box::new(l),
397
398
rhs: Box::new(r),
398
399
}.ast(lo..hi)
399
400
)},
400
- <ExprPrecedence11 >,
401
+ <ExprPrecedence12 >,
401
402
}
402
403
403
- ExprPrecedence11 : ast::Expr = {
404
- <lo:@L> "NOT" <r:ExprPrecedence11 > <hi:@R> =>
404
+ ExprPrecedence12 : ast::Expr = {
405
+ <lo:@L> "NOT" <r:ExprPrecedence12 > <hi:@R> =>
405
406
ast::Expr{ kind: ast::ExprKind::UniOp(
406
407
ast::UniOp {
407
408
kind: ast::UniOpKind::Not,
408
409
expr: Box::new(r),
409
410
}.ast(lo..hi)
410
411
)},
411
- <ExprPrecedence10 >,
412
+ <ExprPrecedence11 >,
412
413
}
413
414
414
- ExprPrecedence10 : ast::Expr = {
415
- <lo:@L> <l:ExprPrecedence10 > "IS" <r:ExprPrecedence09 > <hi:@R> =>
415
+ ExprPrecedence11 : ast::Expr = {
416
+ <lo:@L> <l:ExprPrecedence11 > "IS" <r:ExprPrecedence10 > <hi:@R> =>
416
417
ast::Expr{ kind: ast::ExprKind::BinOp(
417
418
ast::BinOp {
418
419
kind: ast::BinOpKind::Is,
419
420
lhs: Box::new(l),
420
421
rhs: Box::new(r),
421
422
}.ast(lo..hi)
422
423
)},
423
- <lo:@L> <l:ExprPrecedence10 > "IS" "NOT" <r:ExprPrecedence09 > <hi:@R> => {
424
+ <lo:@L> <l:ExprPrecedence11 > "IS" "NOT" <r:ExprPrecedence10 > <hi:@R> => {
424
425
let is = ast::Expr{ kind: ast::ExprKind::BinOp(
425
426
ast::BinOp {
426
427
kind: ast::BinOpKind::Is,
@@ -435,77 +436,77 @@ ExprPrecedence10: ast::Expr = {
435
436
}.ast(lo..hi)
436
437
)}
437
438
},
438
- <ExprPrecedence09 >
439
+ <ExprPrecedence10 >
439
440
}
440
441
441
- ExprPrecedence09 : ast::Expr = {
442
- <lo:@L> <l:ExprPrecedence09 > "=" <r:ExprPrecedence08 > <hi:@R> =>
442
+ ExprPrecedence10 : ast::Expr = {
443
+ <lo:@L> <l:ExprPrecedence10 > "=" <r:ExprPrecedence09 > <hi:@R> =>
443
444
ast::Expr{ kind: ast::ExprKind::BinOp(
444
445
ast::BinOp {
445
446
kind: ast::BinOpKind::Eq,
446
447
lhs: Box::new(l),
447
448
rhs: Box::new(r),
448
449
}.ast(lo..hi)
449
450
)},
450
- <lo:@L> <l:ExprPrecedence09 > "!=" <r:ExprPrecedence08 > <hi:@R> =>
451
+ <lo:@L> <l:ExprPrecedence10 > "!=" <r:ExprPrecedence09 > <hi:@R> =>
451
452
ast::Expr{ kind: ast::ExprKind::BinOp(
452
453
ast::BinOp {
453
454
kind: ast::BinOpKind::Ne,
454
455
lhs: Box::new(l),
455
456
rhs: Box::new(r),
456
457
}.ast(lo..hi)
457
458
)},
458
- <lo:@L> <l:ExprPrecedence09 > "<>" <r:ExprPrecedence08 > <hi:@R> =>
459
+ <lo:@L> <l:ExprPrecedence10 > "<>" <r:ExprPrecedence09 > <hi:@R> =>
459
460
ast::Expr{ kind: ast::ExprKind::BinOp(
460
461
ast::BinOp {
461
462
kind: ast::BinOpKind::Ne,
462
463
lhs: Box::new(l),
463
464
rhs: Box::new(r),
464
465
}.ast(lo..hi)
465
466
)},
466
- <ExprPrecedence08 >,
467
+ <ExprPrecedence09 >,
467
468
}
468
469
469
- ExprPrecedence08 : ast::Expr = {
470
- <lo:@L> <l:ExprPrecedence08> "<" <r:ExprPrecedence07 > <hi:@R> =>
470
+ ExprPrecedence09 : ast::Expr = {
471
+ <lo:@L> <l:ExprPrecedence08> "<" <r:ExprPrecedence08 > <hi:@R> =>
471
472
ast::Expr{ kind: ast::ExprKind::BinOp(
472
473
ast::BinOp {
473
474
kind: ast::BinOpKind::Lt,
474
475
lhs: Box::new(l),
475
476
rhs: Box::new(r),
476
477
}.ast(lo..hi)
477
478
)},
478
- <lo:@L> <l:ExprPrecedence08> ">" <r:ExprPrecedence07 > <hi:@R> =>
479
+ <lo:@L> <l:ExprPrecedence08> ">" <r:ExprPrecedence08 > <hi:@R> =>
479
480
ast::Expr{ kind: ast::ExprKind::BinOp(
480
481
ast::BinOp {
481
482
kind: ast::BinOpKind::Gt,
482
483
lhs: Box::new(l),
483
484
rhs: Box::new(r),
484
485
}.ast(lo..hi)
485
486
)},
486
- <lo:@L> <l:ExprPrecedence08> "<=" <r:ExprPrecedence07 > <hi:@R> =>
487
+ <lo:@L> <l:ExprPrecedence08> "<=" <r:ExprPrecedence08 > <hi:@R> =>
487
488
ast::Expr{ kind: ast::ExprKind::BinOp(
488
489
ast::BinOp {
489
490
kind: ast::BinOpKind::Lte,
490
491
lhs: Box::new(l),
491
492
rhs: Box::new(r),
492
493
}.ast(lo..hi)
493
494
)},
494
- <lo:@L> <l:ExprPrecedence08> ">=" <r:ExprPrecedence07 > <hi:@R> =>
495
+ <lo:@L> <l:ExprPrecedence08> ">=" <r:ExprPrecedence08 > <hi:@R> =>
495
496
ast::Expr{ kind: ast::ExprKind::BinOp(
496
497
ast::BinOp {
497
498
kind: ast::BinOpKind::Gte,
498
499
lhs: Box::new(l),
499
500
rhs: Box::new(r),
500
501
}.ast(lo..hi)
501
502
)},
502
- <ExprPrecedence07 >,
503
+ <ExprPrecedence08 >,
503
504
}
504
505
505
- ExprPrecedence07 : ast::Expr = {
506
- <lo:@L> <value:ExprPrecedence07 > "BETWEEN" <from:ExprPrecedence06 > "AND" <to:ExprPrecedence06 > <hi:@R> =>
506
+ ExprPrecedence08 : ast::Expr = {
507
+ <lo:@L> <value:ExprPrecedence08 > "BETWEEN" <from:ExprPrecedence07 > "AND" <to:ExprPrecedence07 > <hi:@R> =>
507
508
ast::Expr{ kind: ast::ExprKind::Between( ast::Between{ value: Box::new(value), from: Box::new(from), to: Box::new(to) }.ast(lo..hi) ) },
508
- <lo:@L> <value:ExprPrecedence07 > "NOT" "BETWEEN" <from:ExprPrecedence06 > "AND" <to:ExprPrecedence06 > <hi:@R> => {
509
+ <lo:@L> <value:ExprPrecedence08 > "NOT" "BETWEEN" <from:ExprPrecedence07 > "AND" <to:ExprPrecedence07 > <hi:@R> => {
509
510
let between = ast::Expr{ kind: ast::ExprKind::Between( ast::Between{ value: Box::new(value), from: Box::new(from), to: Box::new(to) }.ast(lo..hi) ) };
510
511
ast::Expr{ kind: ast::ExprKind::UniOp(
511
512
ast::UniOp {
@@ -514,9 +515,9 @@ ExprPrecedence07: ast::Expr = {
514
515
}.ast(lo..hi)
515
516
)}
516
517
},
517
- <lo:@L> <value:ExprPrecedence07 > "LIKE" <pattern:ExprPrecedence06 > <escape:LikeEscape?> <hi:@R> =>
518
+ <lo:@L> <value:ExprPrecedence08 > "LIKE" <pattern:ExprPrecedence07 > <escape:LikeEscape?> <hi:@R> =>
518
519
ast::Expr{ kind: ast::ExprKind::Like( ast::Like{ value: Box::new(value), pattern: Box::new(pattern), escape }.ast(lo..hi) ) },
519
- <lo:@L> <value:ExprPrecedence07 > "NOT" "LIKE" <pattern:ExprPrecedence06 > <escape:LikeEscape?> <hi:@R> => {
520
+ <lo:@L> <value:ExprPrecedence08 > "NOT" "LIKE" <pattern:ExprPrecedence07 > <escape:LikeEscape?> <hi:@R> => {
520
521
let like = ast::Expr{ kind: ast::ExprKind::Like( ast::Like{ value: Box::new(value), pattern: Box::new(pattern), escape }.ast(lo..hi) ) };
521
522
ast::Expr{ kind: ast::ExprKind::UniOp(
522
523
ast::UniOp {
@@ -525,9 +526,9 @@ ExprPrecedence07: ast::Expr = {
525
526
}.ast(lo..hi)
526
527
)}
527
528
},
528
- <lo:@L> <l:ExprPrecedence07 > "IN" <r:ExprPrecedence06 > <hi:@R> =>
529
+ <lo:@L> <l:ExprPrecedence08 > "IN" <r:ExprPrecedence07 > <hi:@R> =>
529
530
ast::Expr{ kind: ast::ExprKind::In( ast::In{ operands: vec![Box::new(l),Box::new(r)] }.ast(lo..hi) ) },
530
- <lo:@L> <l:ExprPrecedence07 > "NOT" "IN" <r:ExprPrecedence06 > <hi:@R> => {
531
+ <lo:@L> <l:ExprPrecedence08 > "NOT" "IN" <r:ExprPrecedence07 > <hi:@R> => {
531
532
let in_expr = ast::Expr{ kind: ast::ExprKind::In( ast::In{ operands: vec![Box::new(l),Box::new(r)] }.ast(lo..hi) ) };
532
533
ast::Expr{ kind: ast::ExprKind::UniOp(
533
534
ast::UniOp {
@@ -536,11 +537,23 @@ ExprPrecedence07: ast::Expr = {
536
537
}.ast(lo..hi)
537
538
)}
538
539
},
539
- <ExprPrecedence06 >,
540
+ <ExprPrecedence07 >,
540
541
}
541
542
#[inline]
542
543
LikeEscape: Box<ast::Expr> = {
543
- "ESCAPE" <e:ExprPrecedence06> => Box::new(e)
544
+ "ESCAPE" <e:ExprPrecedence07> => Box::new(e)
545
+ }
546
+
547
+ ExprPrecedence07: ast::Expr = {
548
+ <lo:@L> <l:ExprPrecedence07> "||" <r:ExprPrecedence06> <hi:@R> =>
549
+ ast::Expr{ kind: ast::ExprKind::BinOp(
550
+ ast::BinOp {
551
+ kind: ast::BinOpKind::Concat,
552
+ lhs: Box::new(l),
553
+ rhs: Box::new(r),
554
+ }.ast(lo..hi)
555
+ )},
556
+ <ExprPrecedence06>,
544
557
}
545
558
546
559
ExprPrecedence06: ast::Expr = {
@@ -822,6 +835,7 @@ extern {
822
835
"/" => lexer::Token::Slash,
823
836
"%" => lexer::Token::Percent,
824
837
"^" => lexer::Token::Caret,
838
+ "||" => lexer::Token::DblPipe,
825
839
826
840
"=" => lexer::Token::Equal,
827
841
"==" => lexer::Token::EqualEqual,
0 commit comments