Parse a copy statement
(&mut self)
| 6700 | |
| 6701 | /// Parse a copy statement |
| 6702 | fn parse_copy(&mut self) -> Result<Statement<Raw>, ParserStatementError> { |
| 6703 | // We support an optional "INTO" keyword for COPY INTO <table> FROM |
| 6704 | let maybe_into_pos = if self.parse_keyword(Keyword::Into) { |
| 6705 | Some(self.peek_prev_pos()) |
| 6706 | } else { |
| 6707 | None |
| 6708 | }; |
| 6709 | |
| 6710 | let relation = if self.consume_token(&Token::LParen) { |
| 6711 | let query = self.parse_statement()?.ast; |
| 6712 | self.expect_token(&Token::RParen) |
| 6713 | .map_parser_err(StatementKind::Copy)?; |
| 6714 | match query { |
| 6715 | Statement::Select(stmt) => CopyRelation::Select(stmt), |
| 6716 | Statement::Subscribe(stmt) => CopyRelation::Subscribe(stmt), |
| 6717 | _ => { |
| 6718 | return parser_err!(self, self.peek_prev_pos(), "unsupported query in COPY") |
| 6719 | .map_parser_err(StatementKind::Copy); |
| 6720 | } |
| 6721 | } |
| 6722 | } else { |
| 6723 | let name = self.parse_raw_name().map_parser_err(StatementKind::Copy)?; |
| 6724 | let columns = self |
| 6725 | .parse_parenthesized_column_list(Optional) |
| 6726 | .map_parser_err(StatementKind::Copy)?; |
| 6727 | CopyRelation::Named { name, columns } |
| 6728 | }; |
| 6729 | let (direction, target) = match self |
| 6730 | .expect_one_of_keywords(&[FROM, TO]) |
| 6731 | .map_parser_err(StatementKind::Copy)? |
| 6732 | { |
| 6733 | FROM => { |
| 6734 | if let CopyRelation::Named { .. } = relation { |
| 6735 | // Ok. |
| 6736 | } else { |
| 6737 | return parser_err!( |
| 6738 | self, |
| 6739 | self.peek_prev_pos(), |
| 6740 | "queries not allowed in COPY FROM" |
| 6741 | ) |
| 6742 | .map_no_statement_parser_err(); |
| 6743 | } |
| 6744 | if self.parse_keyword(STDIN) { |
| 6745 | (CopyDirection::From, CopyTarget::Stdin) |
| 6746 | } else { |
| 6747 | let url_expr = self.parse_expr().map_parser_err(StatementKind::Copy)?; |
| 6748 | (CopyDirection::From, CopyTarget::Expr(url_expr)) |
| 6749 | } |
| 6750 | } |
| 6751 | TO => { |
| 6752 | // We only support the INTO keyword for 'COPY FROM'. |
| 6753 | if let Some(into_pos) = maybe_into_pos { |
| 6754 | return self |
| 6755 | .expected(into_pos, "identifier", Some(Token::Keyword(Keyword::Into))) |
| 6756 | .map_parser_err(StatementKind::Copy); |
| 6757 | } |
| 6758 | |
| 6759 | if self.parse_keyword(STDOUT) { |
no test coverage detected