Parse a SQL `COPY TO` statement
(&mut self)
| 625 | |
| 626 | /// Parse a SQL `COPY TO` statement |
| 627 | pub fn parse_copy(&mut self) -> Result<Statement, DataFusionError> { |
| 628 | // parse as a query |
| 629 | let source = if self.parser.consume_token(&Token::LParen) { |
| 630 | let query = self.parser.parse_query()?; |
| 631 | self.parser.expect_token(&Token::RParen)?; |
| 632 | CopyToSource::Query(query) |
| 633 | } else { |
| 634 | // parse as table reference |
| 635 | let table_name = self.parser.parse_object_name(true)?; |
| 636 | CopyToSource::Relation(table_name) |
| 637 | }; |
| 638 | |
| 639 | #[derive(Default)] |
| 640 | struct Builder { |
| 641 | stored_as: Option<String>, |
| 642 | target: Option<String>, |
| 643 | partitioned_by: Option<Vec<String>>, |
| 644 | options: Option<Vec<(String, Value)>>, |
| 645 | } |
| 646 | |
| 647 | let mut builder = Builder::default(); |
| 648 | |
| 649 | loop { |
| 650 | if let Some(keyword) = self.parser.parse_one_of_keywords(&[ |
| 651 | Keyword::STORED, |
| 652 | Keyword::TO, |
| 653 | Keyword::PARTITIONED, |
| 654 | Keyword::OPTIONS, |
| 655 | Keyword::WITH, |
| 656 | ]) { |
| 657 | match keyword { |
| 658 | Keyword::STORED => { |
| 659 | self.parser.expect_keyword(Keyword::AS)?; |
| 660 | ensure_not_set(&builder.stored_as, "STORED AS")?; |
| 661 | builder.stored_as = Some(self.parse_file_format()?); |
| 662 | } |
| 663 | Keyword::TO => { |
| 664 | ensure_not_set(&builder.target, "TO")?; |
| 665 | builder.target = Some(self.parser.parse_literal_string()?); |
| 666 | } |
| 667 | Keyword::WITH => { |
| 668 | self.parser.expect_keyword(Keyword::HEADER)?; |
| 669 | self.parser.expect_keyword(Keyword::ROW)?; |
| 670 | return parser_err!( |
| 671 | "WITH HEADER ROW clause is no longer in use. Please use the OPTIONS clause with 'format.has_header' set appropriately, e.g., OPTIONS ('format.has_header' 'true')" |
| 672 | )?; |
| 673 | } |
| 674 | Keyword::PARTITIONED => { |
| 675 | self.parser.expect_keyword(Keyword::BY)?; |
| 676 | ensure_not_set(&builder.partitioned_by, "PARTITIONED BY")?; |
| 677 | builder.partitioned_by = Some(self.parse_partitions()?); |
| 678 | } |
| 679 | Keyword::OPTIONS => { |
| 680 | ensure_not_set(&builder.options, "OPTIONS")?; |
| 681 | builder.options = Some(self.parse_value_options()?); |
| 682 | } |
| 683 | _ => { |
| 684 | unreachable!() |
no test coverage detected