parseWindowSpec parses a window specification (PARTITION BY, ORDER BY, frame clause). Supports both inline specs OVER (...) and named window references OVER w (SQL:2003 §7.11).
()
| 357 | // parseWindowSpec parses a window specification (PARTITION BY, ORDER BY, frame clause). |
| 358 | // Supports both inline specs OVER (...) and named window references OVER w (SQL:2003 §7.11). |
| 359 | func (p *Parser) parseWindowSpec() (*ast.WindowSpec, error) { |
| 360 | // Named window reference: OVER w - bare identifier, no parentheses. |
| 361 | // This must be checked before the '(' path so that e.g. OVER w is not |
| 362 | // mistakenly rejected. |
| 363 | if p.isIdentifier() { |
| 364 | spec := &ast.WindowSpec{Name: p.currentToken.Token.Value} |
| 365 | p.advance() |
| 366 | return spec, nil |
| 367 | } |
| 368 | |
| 369 | // Expect opening parenthesis |
| 370 | if !p.isType(models.TokenTypeLParen) { |
| 371 | return nil, p.expectedError("(") |
| 372 | } |
| 373 | p.advance() // Consume ( |
| 374 | |
| 375 | windowSpec := &ast.WindowSpec{} |
| 376 | |
| 377 | // Parse PARTITION BY clause |
| 378 | if p.isType(models.TokenTypePartition) { |
| 379 | p.advance() // Consume PARTITION |
| 380 | if !p.isType(models.TokenTypeBy) { |
| 381 | return nil, p.expectedError("BY after PARTITION") |
| 382 | } |
| 383 | p.advance() // Consume BY |
| 384 | |
| 385 | // Parse partition expressions |
| 386 | for { |
| 387 | expr, err := p.parseExpression() |
| 388 | if err != nil { |
| 389 | return nil, err |
| 390 | } |
| 391 | windowSpec.PartitionBy = append(windowSpec.PartitionBy, expr) |
| 392 | |
| 393 | if p.isType(models.TokenTypeComma) { |
| 394 | p.advance() // Consume comma |
| 395 | } else { |
| 396 | break |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | // Parse ORDER BY clause |
| 402 | if p.isType(models.TokenTypeOrder) { |
| 403 | p.advance() // Consume ORDER |
| 404 | if !p.isType(models.TokenTypeBy) { |
| 405 | return nil, p.expectedError("BY after ORDER") |
| 406 | } |
| 407 | p.advance() // Consume BY |
| 408 | |
| 409 | // Parse order expressions |
| 410 | for { |
| 411 | expr, err := p.parseExpression() |
| 412 | if err != nil { |
| 413 | return nil, err |
| 414 | } |
| 415 | |
| 416 | // Create OrderByExpression with defaults |
no test coverage detected