parseSelectCommand - Return ast.SelectCommand created from tokens and validate the syntax Example of input parsable to the ast.SelectCommand: SELECT col1, col2, col3 FROM tbl;
()
| 240 | // Example of input parsable to the ast.SelectCommand: |
| 241 | // SELECT col1, col2, col3 FROM tbl; |
| 242 | func (parser *Parser) parseSelectCommand() (ast.Command, error) { |
| 243 | // token.SELECT already at current position in parser |
| 244 | selectCommand := &ast.SelectCommand{Token: parser.currentToken} |
| 245 | |
| 246 | // Ignore token.SELECT |
| 247 | parser.nextToken() |
| 248 | |
| 249 | // optional DISTINCT |
| 250 | if parser.currentToken.Type == token.DISTINCT { |
| 251 | selectCommand.HasDistinct = true |
| 252 | |
| 253 | // Ignore token.DISTINCT |
| 254 | parser.nextToken() |
| 255 | } |
| 256 | |
| 257 | err := validateToken(parser.currentToken.Type, []token.Type{token.ASTERISK, token.IDENT, token.MAX, token.MIN, token.SUM, token.AVG, token.COUNT}) |
| 258 | if err != nil { |
| 259 | return nil, err |
| 260 | } |
| 261 | |
| 262 | if parser.currentToken.Type == token.ASTERISK { |
| 263 | selectCommand.Space = append(selectCommand.Space, ast.Space{ColumnName: parser.currentToken}) |
| 264 | parser.nextToken() |
| 265 | } else { |
| 266 | for parser.currentToken.Type == token.IDENT || isAggregateFunction(parser.currentToken.Type) { |
| 267 | if parser.currentToken.Type != token.IDENT { |
| 268 | aggregateFunction := parser.currentToken |
| 269 | parser.nextToken() |
| 270 | err := validateTokenAndSkip(parser, []token.Type{token.LPAREN}) |
| 271 | if err != nil { |
| 272 | return nil, err |
| 273 | } |
| 274 | if aggregateFunction.Type == token.COUNT { |
| 275 | err = validateToken(parser.currentToken.Type, []token.Type{token.IDENT, token.ASTERISK}) |
| 276 | } else { |
| 277 | err = validateToken(parser.currentToken.Type, []token.Type{token.IDENT}) |
| 278 | } |
| 279 | if err != nil { |
| 280 | return nil, err |
| 281 | } |
| 282 | selectCommand.Space = append(selectCommand.Space, ast.Space{ColumnName: parser.currentToken, AggregateFunc: &aggregateFunction}) |
| 283 | parser.nextToken() |
| 284 | |
| 285 | err = validateTokenAndSkip(parser, []token.Type{token.RPAREN}) |
| 286 | if err != nil { |
| 287 | return nil, err |
| 288 | } |
| 289 | } else { |
| 290 | // Get column name |
| 291 | err = validateToken(parser.currentToken.Type, []token.Type{token.IDENT}) |
| 292 | if err != nil { |
| 293 | return nil, err |
| 294 | } |
| 295 | selectCommand.Space = append(selectCommand.Space, ast.Space{ColumnName: parser.currentToken}) |
| 296 | parser.nextToken() |
| 297 | } |
| 298 | |
| 299 | if parser.currentToken.Type != token.COMMA { |
no test coverage detected