SUM(salary) OVER (PARTITION BY dept ORDER BY date ROWS UNBOUNDED PRECEDING) -> window function with frame
(funcName string)
| 28 | |
| 29 | // SUM(salary) OVER (PARTITION BY dept ORDER BY date ROWS UNBOUNDED PRECEDING) -> window function with frame |
| 30 | func (p *Parser) parseFunctionCall(funcName string) (*ast.FunctionCall, error) { |
| 31 | // Expect opening parenthesis |
| 32 | if !p.isType(models.TokenTypeLParen) { |
| 33 | return nil, p.expectedError("(") |
| 34 | } |
| 35 | p.advance() // Consume ( |
| 36 | |
| 37 | // Parse function arguments |
| 38 | var arguments []ast.Expression |
| 39 | var distinct bool |
| 40 | |
| 41 | // Check for DISTINCT keyword |
| 42 | if p.isType(models.TokenTypeDistinct) { |
| 43 | distinct = true |
| 44 | p.advance() |
| 45 | } |
| 46 | |
| 47 | // Parse arguments if not empty |
| 48 | if !p.isType(models.TokenTypeRParen) { |
| 49 | for !p.isType(models.TokenTypeOrder) { |
| 50 | // Named argument form: `name => expr` (Snowflake FLATTEN, |
| 51 | // BigQuery, Oracle, PostgreSQL procedural calls). Detect by a |
| 52 | // bare identifier immediately followed by =>. |
| 53 | if p.isIdentifier() && |
| 54 | p.peekToken().Token.Type == models.TokenTypeRArrow { |
| 55 | namePos := p.currentLocation() |
| 56 | argName := p.currentToken.Token.Value |
| 57 | p.advance() // name |
| 58 | p.advance() // => |
| 59 | value, err := p.parseExpression() |
| 60 | if err != nil { |
| 61 | return nil, err |
| 62 | } |
| 63 | arguments = append(arguments, &ast.NamedArgument{ |
| 64 | Name: argName, |
| 65 | Value: value, |
| 66 | Pos: namePos, |
| 67 | }) |
| 68 | if p.isType(models.TokenTypeComma) { |
| 69 | p.advance() |
| 70 | continue |
| 71 | } |
| 72 | if p.isType(models.TokenTypeRParen) { |
| 73 | break |
| 74 | } |
| 75 | return nil, p.expectedError(", or )") |
| 76 | } |
| 77 | |
| 78 | arg, err := p.parseExpression() |
| 79 | if err != nil { |
| 80 | return nil, err |
| 81 | } |
| 82 | arguments = append(arguments, arg) |
| 83 | |
| 84 | // Check for comma or end of arguments |
| 85 | if p.isType(models.TokenTypeComma) { |
| 86 | p.advance() // Consume comma |
| 87 | } else if p.isType(models.TokenTypeRParen) || p.isType(models.TokenTypeOrder) { |
no test coverage detected