@@ -20,6 +20,7 @@ const (
2020 PrecedenceMulDivMod
2121 PrecedenceBracket
2222 PrecedenceArrow
23+ PrecedenceDot
2324 PrecedenceDoubleColon
2425)
2526
@@ -56,6 +57,8 @@ func (p *Parser) getNextPrecedence() int {
5657 return PrecedenceBracket
5758 case p .matchTokenKind (opTypeCast ):
5859 return PrecedenceDoubleColon
60+ case p .matchTokenKind (TokenDot ):
61+ return PrecedenceDot
5962 case p .matchKeyword (KeywordBetween ), p .matchKeyword (KeywordLike ), p .matchKeyword (KeywordIlike ):
6063 return PrecedenceBetweenLike
6164 case p .matchKeyword (KeywordIn ):
@@ -78,7 +81,7 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
7881 p .matchTokenKind (opTypeDiv ), p .matchTokenKind (opTypeMod ),
7982 p .matchKeyword (KeywordIn ), p .matchKeyword (KeywordLike ),
8083 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 ):
8285 op := p .last ().ToString ()
8386 _ = p .lexer .consumeToken ()
8487 rightExpr , err := p .parseSubExpr (p .Pos (), precedence )
@@ -90,6 +93,38 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
9093 Operation : TokenKind (op ),
9194 RightExpr : rightExpr ,
9295 }, 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
93128 case p .matchKeyword (KeywordBetween ):
94129 return p .parseBetweenClause (expr )
95130 case p .matchKeyword (KeywordGlobal ):
@@ -106,7 +141,24 @@ func (p *Parser) parseInfix(expr Expr, precedence int) (Expr, error) {
106141 Operation : "GLOBAL IN" ,
107142 RightExpr : rightExpr ,
108143 }, 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
110162 case p .matchKeyword (KeywordNot ):
111163 _ = p .lexer .consumeToken ()
112164 switch {
@@ -331,6 +383,8 @@ func (p *Parser) parseColumnExpr(pos Pos) (Expr, error) { //nolint:funlen
331383 return p .parseQueryParam (p .Pos ())
332384 }
333385 return p .parseMapLiteral (p .Pos ())
386+ case p .matchTokenKind (TokenDot ):
387+ return p .parseNumber (p .Pos ())
334388 case p .matchTokenKind (opTypeQuery ):
335389 // Placeholder `?`
336390 _ = p .lexer .consumeToken ()
0 commit comments