(&mut self)
| 3558 | } |
| 3559 | |
| 3560 | fn parse_create_sink(&mut self) -> Result<Statement<Raw>, ParserError> { |
| 3561 | self.expect_keyword(SINK)?; |
| 3562 | let if_not_exists = self.parse_if_not_exists()?; |
| 3563 | |
| 3564 | let mut name = Some(self.parse_item_name()?); |
| 3565 | |
| 3566 | // Sniff out `CREATE SINK IN CLUSTER <c> ...` and `CREATE SINK FROM |
| 3567 | // <view>...` and ensure they are parsed as nameless `CREATE SINK` |
| 3568 | // commands. |
| 3569 | // |
| 3570 | // This is a bit gross, but we didn't have the foresight to make |
| 3571 | // `IN` and `FROM` reserved keywords for sink names. |
| 3572 | if (name == Some(UnresolvedItemName::unqualified(ident!("in"))) |
| 3573 | && self.peek_keyword(CLUSTER)) |
| 3574 | || (name == Some(UnresolvedItemName::unqualified(ident!("from"))) |
| 3575 | && !self.peek_keyword(FROM)) |
| 3576 | { |
| 3577 | name = None; |
| 3578 | self.prev_token(); |
| 3579 | } |
| 3580 | |
| 3581 | let in_cluster = self.parse_optional_in_cluster()?; |
| 3582 | self.expect_keyword(FROM)?; |
| 3583 | let from = self.parse_raw_name()?; |
| 3584 | self.expect_keyword(INTO)?; |
| 3585 | let connection = self.parse_create_sink_connection()?; |
| 3586 | |
| 3587 | let statement = match connection { |
| 3588 | conn @ CreateSinkConnection::Kafka { .. } => { |
| 3589 | self.parse_create_kafka_sink(name, in_cluster, from, if_not_exists, conn) |
| 3590 | } |
| 3591 | conn @ CreateSinkConnection::Iceberg { .. } => { |
| 3592 | self.parse_create_iceberg_sink(name, in_cluster, from, if_not_exists, conn) |
| 3593 | } |
| 3594 | }?; |
| 3595 | |
| 3596 | Ok(Statement::CreateSink(statement)) |
| 3597 | } |
| 3598 | |
| 3599 | /// Parse the name of a CREATE SINK optional parameter |
| 3600 | fn parse_create_sink_option_name(&mut self) -> Result<CreateSinkOptionName, ParserError> { |
no test coverage detected