(&mut self, name: RawItemName)
| 828 | } |
| 829 | |
| 830 | fn parse_function(&mut self, name: RawItemName) -> Result<Function<Raw>, ParserError> { |
| 831 | self.expect_token(&Token::LParen)?; |
| 832 | let distinct = matches!( |
| 833 | self.parse_at_most_one_keyword(&[ALL, DISTINCT], &format!("function: {}", name))?, |
| 834 | Some(DISTINCT), |
| 835 | ); |
| 836 | let args = self.parse_optional_args(true)?; |
| 837 | |
| 838 | if distinct && matches!(args, FunctionArgs::Star) { |
| 839 | return Err(self.error( |
| 840 | self.peek_prev_pos() - 1, |
| 841 | "DISTINCT * not supported as function args".to_string(), |
| 842 | )); |
| 843 | } |
| 844 | |
| 845 | let filter = if self.parse_keyword(FILTER) { |
| 846 | self.expect_token(&Token::LParen)?; |
| 847 | self.expect_keyword(WHERE)?; |
| 848 | let expr = self.parse_expr()?; |
| 849 | self.expect_token(&Token::RParen)?; |
| 850 | Some(Box::new(expr)) |
| 851 | } else { |
| 852 | None |
| 853 | }; |
| 854 | let over = |
| 855 | if self.peek_keyword(OVER) || self.peek_keyword(IGNORE) || self.peek_keyword(RESPECT) { |
| 856 | // TBD: support window names (`OVER mywin`) in place of inline specification |
| 857 | // https://github.com/MaterializeInc/database-issues/issues/5882 |
| 858 | |
| 859 | let ignore_nulls = self.parse_keywords(&[IGNORE, NULLS]); |
| 860 | let respect_nulls = self.parse_keywords(&[RESPECT, NULLS]); |
| 861 | self.expect_keyword(OVER)?; |
| 862 | |
| 863 | self.expect_token(&Token::LParen)?; |
| 864 | let partition_by = if self.parse_keywords(&[PARTITION, BY]) { |
| 865 | // a list of possibly-qualified column names |
| 866 | self.parse_comma_separated(Parser::parse_expr)? |
| 867 | } else { |
| 868 | vec![] |
| 869 | }; |
| 870 | let order_by = if self.parse_keywords(&[ORDER, BY]) { |
| 871 | self.parse_comma_separated(Parser::parse_order_by_expr)? |
| 872 | } else { |
| 873 | vec![] |
| 874 | }; |
| 875 | let window_frame = if !self.consume_token(&Token::RParen) { |
| 876 | let window_frame = self.parse_window_frame()?; |
| 877 | self.expect_token(&Token::RParen)?; |
| 878 | Some(window_frame) |
| 879 | } else { |
| 880 | None |
| 881 | }; |
| 882 | |
| 883 | Some(WindowSpec { |
| 884 | partition_by, |
| 885 | order_by, |
| 886 | window_frame, |
| 887 | ignore_nulls, |
no test coverage detected