@@ -20,6 +20,7 @@ const (
20
20
PrecedenceMulDivMod
21
21
PrecedenceBracket
22
22
PrecedenceArrow
23
+ PrecedenceDot
23
24
PrecedenceDoubleColon
24
25
)
25
26
@@ -56,6 +57,8 @@ func (p *Parser) getNextPrecedence() int {
56
57
return PrecedenceBracket
57
58
case p .matchTokenKind (opTypeCast ):
58
59
return PrecedenceDoubleColon
60
+ case p .matchTokenKind (TokenDot ):
61
+ return PrecedenceDot
59
62
case p .matchKeyword (KeywordBetween ), p .matchKeyword (KeywordLike ), p .matchKeyword (KeywordIlike ):
60
63
return PrecedenceBetweenLike
61
64
case p .matchKeyword (KeywordIn ):
@@ -78,7 +81,7 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
78
81
p .matchTokenKind (opTypeDiv ), p .matchTokenKind (opTypeMod ),
79
82
p .matchKeyword (KeywordIn ), p .matchKeyword (KeywordLike ),
80
83
p .matchKeyword (KeywordIlike ), p .matchKeyword (KeywordAnd ), p .matchKeyword (KeywordOr ),
81
- p .matchTokenKind (opTypeCast ), p . matchTokenKind ( opTypeArrow ), p .matchTokenKind (opTypeDoubleEQ ):
84
+ p .matchTokenKind (opTypeArrow ), p .matchTokenKind (opTypeDoubleEQ ):
82
85
op := p .last ().ToString ()
83
86
_ = p .lexer .consumeToken ()
84
87
rightExpr , err := p .parseSubExpr (p .Pos (), precedence )
@@ -90,6 +93,38 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
90
93
Operation : TokenKind (op ),
91
94
RightExpr : rightExpr ,
92
95
}, nil
96
+ case p .matchTokenKind (opTypeCast ):
97
+ _ = p .lexer .consumeToken ()
98
+
99
+ if p .matchTokenKind (TokenIdent ) && p .last ().String == "Tuple" {
100
+ name , err := p .parseIdent ()
101
+ if err != nil {
102
+ return nil , err
103
+ }
104
+ if _ , err = p .consumeTokenKind ("(" ); err != nil {
105
+ return nil , err
106
+ }
107
+ // it's a tuple type definition after "::" operator
108
+ rightExpr , err := p .parseNestedType (name , p .Pos ())
109
+ if err != nil {
110
+ return nil , err
111
+ }
112
+ return & BinaryOperation {
113
+ LeftExpr : expr ,
114
+ Operation : opTypeCast ,
115
+ RightExpr : rightExpr ,
116
+ }, nil
117
+ }
118
+
119
+ rightExpr , err := p .parseSubExpr (p .Pos (), precedence )
120
+ if err != nil {
121
+ return nil , err
122
+ }
123
+ return & BinaryOperation {
124
+ LeftExpr : expr ,
125
+ Operation : opTypeCast ,
126
+ RightExpr : rightExpr ,
127
+ }, nil
93
128
case p .matchKeyword (KeywordBetween ):
94
129
return p .parseBetweenClause (expr )
95
130
case p .matchKeyword (KeywordGlobal ):
@@ -106,7 +141,24 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
106
141
Operation : "GLOBAL IN" ,
107
142
RightExpr : rightExpr ,
108
143
}, nil
109
-
144
+ case p .matchTokenKind (TokenDot ):
145
+ _ = p .lexer .consumeToken ()
146
+ // access column with dot notation
147
+ var rightExpr Expr
148
+ var err error
149
+ if p .matchTokenKind (TokenIdent ) {
150
+ rightExpr , err = p .parseIdent ()
151
+ } else {
152
+ rightExpr , err = p .parseDecimal (p .Pos ())
153
+ }
154
+ if err != nil {
155
+ return nil , err
156
+ }
157
+ return & IndexOperation {
158
+ LeftExpr : expr ,
159
+ Operation : TokenDot ,
160
+ Index : rightExpr ,
161
+ }, nil
110
162
case p .matchKeyword (KeywordNot ):
111
163
_ = p .lexer .consumeToken ()
112
164
switch {
@@ -331,6 +383,8 @@ func (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen
331
383
return p .parseQueryParam (p .Pos ())
332
384
}
333
385
return p .parseMapLiteral (p .Pos ())
386
+ case p .matchTokenKind (TokenDot ):
387
+ return p .parseNumber (p .Pos ())
334
388
case p .matchTokenKind (opTypeQuery ):
335
389
// Placeholder `?`
336
390
_ = p .lexer .consumeToken ()
0 commit comments