parseDistinctModifier parses the optional DISTINCT [ON (...)] or ALL keyword immediately after SELECT.
()
| 215 | // parseDistinctModifier parses the optional DISTINCT [ON (...)] or ALL keyword |
| 216 | // immediately after SELECT. |
| 217 | func (p *Parser) parseDistinctModifier() (isDistinct bool, distinctOnColumns []ast.Expression, err error) { |
| 218 | if p.isType(models.TokenTypeDistinct) { |
| 219 | isDistinct = true |
| 220 | p.advance() // Consume DISTINCT |
| 221 | |
| 222 | // PostgreSQL DISTINCT ON (expr, ...) |
| 223 | if p.isType(models.TokenTypeOn) { |
| 224 | p.advance() // Consume ON |
| 225 | |
| 226 | if !p.isType(models.TokenTypeLParen) { |
| 227 | return false, nil, p.expectedError("( after DISTINCT ON") |
| 228 | } |
| 229 | p.advance() // Consume ( |
| 230 | |
| 231 | for { |
| 232 | expr, e := p.parseExpression() |
| 233 | if e != nil { |
| 234 | return false, nil, e |
| 235 | } |
| 236 | distinctOnColumns = append(distinctOnColumns, expr) |
| 237 | if !p.isType(models.TokenTypeComma) { |
| 238 | break |
| 239 | } |
| 240 | p.advance() |
| 241 | } |
| 242 | |
| 243 | if !p.isType(models.TokenTypeRParen) { |
| 244 | return false, nil, p.expectedError(") after DISTINCT ON expression list") |
| 245 | } |
| 246 | p.advance() // Consume ) |
| 247 | } |
| 248 | } else if p.isType(models.TokenTypeAll) { |
| 249 | p.advance() // ALL is the default; just consume it |
| 250 | } |
| 251 | return isDistinct, distinctOnColumns, nil |
| 252 | } |
| 253 | |
| 254 | // parseTopClause parses SQL Server's TOP n [PERCENT] [WITH TIES] clause. |
| 255 | // Returns nil when the current dialect is not SQL Server or TOP is absent. |
no test coverage detected