(
&mut self,
optional: IsOptional,
)
| 5338 | } |
| 5339 | |
| 5340 | fn parse_columns( |
| 5341 | &mut self, |
| 5342 | optional: IsOptional, |
| 5343 | ) -> Result<(Vec<ColumnDef<Raw>>, Vec<TableConstraint<Raw>>), ParserError> { |
| 5344 | let mut columns = vec![]; |
| 5345 | let mut constraints = vec![]; |
| 5346 | |
| 5347 | if !self.consume_token(&Token::LParen) { |
| 5348 | if optional == Optional { |
| 5349 | return Ok((columns, constraints)); |
| 5350 | } else { |
| 5351 | return self.expected( |
| 5352 | self.peek_pos(), |
| 5353 | "a list of columns in parentheses", |
| 5354 | self.peek_token(), |
| 5355 | ); |
| 5356 | } |
| 5357 | } |
| 5358 | if self.consume_token(&Token::RParen) { |
| 5359 | // Tables with zero columns are a PostgreSQL extension. |
| 5360 | return Ok((columns, constraints)); |
| 5361 | } |
| 5362 | |
| 5363 | loop { |
| 5364 | if let Some(constraint) = self.parse_optional_table_constraint()? { |
| 5365 | constraints.push(constraint); |
| 5366 | } else if let Some(column_name) = self.consume_identifier()? { |
| 5367 | let data_type = self.parse_data_type()?; |
| 5368 | let collation = if self.parse_keyword(COLLATE) { |
| 5369 | Some(self.parse_item_name()?) |
| 5370 | } else { |
| 5371 | None |
| 5372 | }; |
| 5373 | let mut options = vec![]; |
| 5374 | loop { |
| 5375 | match self.peek_token() { |
| 5376 | None | Some(Token::Comma) | Some(Token::RParen) => break, |
| 5377 | _ => options.push(self.parse_column_option_def()?), |
| 5378 | } |
| 5379 | } |
| 5380 | |
| 5381 | columns.push(ColumnDef { |
| 5382 | name: column_name, |
| 5383 | data_type, |
| 5384 | collation, |
| 5385 | options, |
| 5386 | }); |
| 5387 | } else { |
| 5388 | return self.expected( |
| 5389 | self.peek_pos(), |
| 5390 | "column name or constraint definition", |
| 5391 | self.peek_token(), |
| 5392 | ); |
| 5393 | } |
| 5394 | if self.consume_token(&Token::Comma) { |
| 5395 | // Continue. |
| 5396 | } else if self.consume_token(&Token::RParen) { |
| 5397 | break; |
no test coverage detected